From 4ab3dc1b297a2d50cab81656f39449779a83caf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Wed, 1 Nov 2017 23:21:01 +0100 Subject: [PATCH] Finished importing the good bits from LW's library --- include/ebcl/DynLib.hh | 8 +- include/ebcl/GameLoop.hh | 30 - include/ebcl/Messages.hh | 282 --- include/ebcl/Mods.hh | 247 --- include/ebcl/Pointers.hh | 18 +- include/ebcl/SRDBinary.hh | 14 +- include/ebcl/SRDData.hh | 19 +- include/ebcl/SRDDefinitions.hh | 14 +- include/ebcl/SRDIO.hh | 12 +- include/ebcl/SRDPPCommands.hh | 101 - include/ebcl/SRDParser.hh | 12 +- include/ebcl/SRDParserConfig.hh | 14 +- include/ebcl/SRDText.hh | 12 +- include/ebcl/Version.hh | 19 - include/ebcl/Version.hh.in | 19 - include/ebcl/inline/DynLib.hh | 10 +- include/ebcl/inline/Messages.hh | 154 -- include/ebcl/inline/Mods.hh | 59 - include/ebcl/inline/SRDBinary.hh | 10 +- include/ebcl/inline/SRDData.hh | 10 +- include/ebcl/inline/SRDDefinitions.hh | 10 +- include/ebcl/inline/SRDIO.hh | 10 +- include/ebcl/inline/SRDParserConfig.hh | 10 +- include/ebcl/inline/SRDText.hh | 10 +- src/Console-Unix.hh | 667 ------ src/Console.cc | 1346 ------------ src/ConsoleLogWriter.cc | 83 - src/CwdFileLogger.cc | 153 -- src/DynLib.cc | 6 +- src/GameLoop.cc | 140 -- src/LW.cc | 603 ------ src/Log.cc | 1041 ---------- src/Messages.cc | 86 - src/ModInterface.cc | 20 - src/Mods.cc | 2646 ------------------------ src/SRDBinary.cc | 6 +- src/SRDData.cc | 37 +- src/SRDDefinitions.cc | 10 +- src/SRDIO.cc | 6 +- src/SRDPPCommands.cc | 2518 ---------------------- src/SRDParser.cc | 4 +- src/SRDParserConfig.cc | 4 +- src/SRDPreproc.cc | 1416 ------------- src/SRDText.cc | 14 +- src/TemplateInstantiation.cc | 4 + src/TextFileLogger.cc | 159 -- src/VFS.cc | 930 --------- src/VFSDrivers.cc | 614 ------ src/files.mk | 32 +- tests/alloc-pool.cc | 6 +- tests/console-edit.cc | 468 ----- tests/console-text.cc | 405 ---- tests/list.mk | 42 +- tests/log-data.cc | 649 ------ tests/ring-buffer.cc | 4 +- tests/run-test.cc | 2 +- tests/srd-bin-reader.cc | 6 +- tests/srd-bin-writer.cc | 6 +- tests/srd-lexer.cc | 4 +- tests/srd-mem-target.cc | 4 +- tests/srd-parser-cfg.cc | 4 +- tests/srd-parser-defs.cc | 4 +- tests/srd-parser.cc | 8 +- tests/srd-preproc-cmd-arithmetic.cc | 877 -------- tests/srd-preproc-cmd-casts.cc | 1100 ---------- tests/srd-preproc-cmd-common.hh | 108 - tests/srd-preproc-cmd-compare.cc | 340 --- tests/srd-preproc-cmd-core.cc | 1303 ------------ tests/srd-preproc-cmd-functions.cc | 441 ---- tests/srd-preproc-cmd-input.cc | 543 ----- tests/srd-preproc-cmd-introspect.cc | 322 --- tests/srd-preproc-cmd-logic.cc | 609 ------ tests/srd-preproc-cmd-macros.cc | 243 --- tests/srd-preproc-cmd-misc.cc | 165 -- tests/srd-preproc-cmd-strings.cc | 931 --------- tests/srd-preproc-cmd-variables.cc | 372 ---- tests/srd-preproc-core.cc | 245 --- tests/srd-preproc-location.hh | 133 -- tests/srd-preproc-tracking.cc | 676 ------ tests/srd-text-writer.cc | 6 +- tests/stream-file-input.cc | 268 --- tests/vfs.cc | 318 --- 82 files changed, 177 insertions(+), 24084 deletions(-) delete mode 100644 include/ebcl/GameLoop.hh delete mode 100644 include/ebcl/Messages.hh delete mode 100644 include/ebcl/Mods.hh delete mode 100644 include/ebcl/SRDPPCommands.hh delete mode 100644 include/ebcl/Version.hh delete mode 100644 include/ebcl/Version.hh.in delete mode 100644 include/ebcl/inline/Messages.hh delete mode 100644 include/ebcl/inline/Mods.hh delete mode 100644 src/Console-Unix.hh delete mode 100644 src/Console.cc delete mode 100644 src/ConsoleLogWriter.cc delete mode 100644 src/CwdFileLogger.cc delete mode 100644 src/GameLoop.cc delete mode 100644 src/LW.cc delete mode 100644 src/Log.cc delete mode 100644 src/Messages.cc delete mode 100644 src/ModInterface.cc delete mode 100644 src/Mods.cc delete mode 100644 src/SRDPPCommands.cc delete mode 100644 src/SRDPreproc.cc delete mode 100644 src/TextFileLogger.cc delete mode 100644 src/VFS.cc delete mode 100644 src/VFSDrivers.cc delete mode 100644 tests/console-edit.cc delete mode 100644 tests/console-text.cc delete mode 100644 tests/log-data.cc delete mode 100644 tests/srd-preproc-cmd-arithmetic.cc delete mode 100644 tests/srd-preproc-cmd-casts.cc delete mode 100644 tests/srd-preproc-cmd-common.hh delete mode 100644 tests/srd-preproc-cmd-compare.cc delete mode 100644 tests/srd-preproc-cmd-core.cc delete mode 100644 tests/srd-preproc-cmd-functions.cc delete mode 100644 tests/srd-preproc-cmd-input.cc delete mode 100644 tests/srd-preproc-cmd-introspect.cc delete mode 100644 tests/srd-preproc-cmd-logic.cc delete mode 100644 tests/srd-preproc-cmd-macros.cc delete mode 100644 tests/srd-preproc-cmd-misc.cc delete mode 100644 tests/srd-preproc-cmd-strings.cc delete mode 100644 tests/srd-preproc-cmd-variables.cc delete mode 100644 tests/srd-preproc-core.cc delete mode 100644 tests/srd-preproc-location.hh delete mode 100644 tests/srd-preproc-tracking.cc delete mode 100644 tests/stream-file-input.cc delete mode 100644 tests/vfs.cc diff --git a/include/ebcl/DynLib.hh b/include/ebcl/DynLib.hh index 642f7e4..9fe8d03 100644 --- a/include/ebcl/DynLib.hh +++ b/include/ebcl/DynLib.hh @@ -5,9 +5,9 @@ #ifndef _H_EBCL_DYNLIB #define _H_EBCL_DYNLIB -#include -#include -namespace lw { +#include +#include +namespace ebcl { /*= DYNAMIC LIBRARY SUPPORT ==================================================*/ @@ -45,4 +45,4 @@ M_CLASS_POINTERS( DynLib ); } // namespace lw #endif // _H_EBCL_DYNLIB -#include +#include diff --git a/include/ebcl/GameLoop.hh b/include/ebcl/GameLoop.hh deleted file mode 100644 index f82677a..0000000 --- a/include/ebcl/GameLoop.hh +++ /dev/null @@ -1,30 +0,0 @@ -/******************************************************************************/ -/* GAME'S MAIN LOOP ***********************************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_GAMELOOP -#define _H_LW_LIB_GAMELOOP -#include -namespace lw { - - -/*= GAME LOOP ================================================================*/ - -class T_GameLoop : public A_PrivateImplementation -{ - public: - T_GameLoop( ) noexcept; - T_GameLoop( T_GameLoop const& ) = delete; - T_GameLoop( T_GameLoop&& ) = delete; - - bool active( ) const noexcept; - void start( ) noexcept; - void shutdown( ) noexcept; - - void putMessage( T_UIMessage&& message ) noexcept; -}; -M_CLASS_POINTERS( GameLoop ); - - -} -#endif // _H_LW_LIB_GAMELOOP diff --git a/include/ebcl/Messages.hh b/include/ebcl/Messages.hh deleted file mode 100644 index 4e288c2..0000000 --- a/include/ebcl/Messages.hh +++ /dev/null @@ -1,282 +0,0 @@ -/******************************************************************************/ -/* UI<=>GAME MESSAGES *********************************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_MESSAGES -#define _H_LW_LIB_MESSAGES -#include -#include -namespace lw { - - -/*= VIEWS ====================================================================*/ - -/* Empty abstract class that serves as a base for game views */ -class A_GameView -{ - public: - virtual ~A_GameView( ) = 0; -}; -M_ABSTRACT_POINTERS( GameView ); - - -/* Abstract class for a view builder - * - * User interfaces need to access the game's data in order to display it. View - * builders provide a way to do that; they are passed to the game's main loop - * by the UI. Once set, they will be used to create and update view data. - */ -class A_ViewBuilder -{ - public: - virtual ~A_ViewBuilder( ) = 0; - - /* This method creates a view instance. It is called twice when the - * builder is installed, in order to create a "double buffer" - one - * view can be sent to the UI while the other is being updated. - */ - virtual OP_GameView createView( ) = 0; - - /* This method is responsible for updating a view instance. */ - virtual void updateView( OP_GameView view ) = 0; -}; -M_ABSTRACT_POINTERS( ViewBuilder ); - - -/*= GAME STATE ===============================================================*/ - -/* State of the main loop */ -enum class E_GameState { - NO_GAME , // No game loaded - GAME_PAUSED , // Game is loaded but not running - GAME_SLOW , // Game is running at slow speed - GAME_NORMAL , // Game is running at normal speed - GAME_FAST // Game is running at high speed -}; -M_LSHIFT_OP( T_StringBuilder , E_GameState ); - - -/*= PROGRESS INFORMATION =====================================================*/ - -/* Progress information for long operations - part (main or sub) */ -class T_ProgressInfoPart -{ - private: - T_String text_; - uint32_t progress_; - uint32_t total_; - - public: - T_ProgressInfoPart( ) = delete; - T_ProgressInfoPart( T_String text , uint32_t progress , uint32_t total ) noexcept; - T_ProgressInfoPart( T_ProgressInfoPart&& other ) noexcept; - T_ProgressInfoPart( T_ProgressInfoPart const& other ); - - T_String const& text( ) const noexcept; - uint32_t progress( ) const noexcept; - uint32_t total( ) const noexcept; -}; - -/* Progress information for long operations - main */ -class T_ProgressInfo -{ - private: - T_ProgressInfoPart main_; - T_Optional< T_ProgressInfoPart > sub_; - - public: - T_ProgressInfo( ) = delete; - T_ProgressInfo( T_String text , uint32_t progress , uint32_t total ) noexcept; - explicit T_ProgressInfo( T_ProgressInfoPart main ) noexcept; - T_ProgressInfo( T_ProgressInfoPart main , T_ProgressInfoPart sub ) noexcept; - T_ProgressInfo( T_ProgressInfoPart main , - T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept; - T_ProgressInfo( T_String text , uint32_t progress , uint32_t total , - T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept; - T_ProgressInfo( T_ProgressInfo&& other ) noexcept; - T_ProgressInfo( T_ProgressInfo const& other ) = delete; - - T_ProgressInfoPart const& main( ) const noexcept; - bool hasSub( ) const noexcept; - T_ProgressInfoPart const& sub( ) const; -}; -M_CLASS_POINTERS( ProgressInfo ); - - -/*= MESSAGES =================================================================*/ - -/* Types of messages sent by the UI to the game */ -enum class E_GameUIMessage { - /* Create a new game - * Data: XXX - */ - NEW , - /* Load an existing game - * Data: uint32_t - game identifier - */ - LOAD , - /* Save the current game - * Data: none - */ - SAVE , - /* Quit the current game - * Data: none - */ - STOP , - /* Quit current game (if any) the exit the main loop - * Data: none - */ - QUIT , - - /* Abort the current operation - * Data: none - */ - ABORT , - - /* Delete a saved game - * Data: uint32_t - game identifier - */ - DELETE , - /* Copy or rename a saved game - * Data: XXX - */ - COPY_OR_RENAME , - - /* Set the current game's speed - * Data: E_GameState (but NO_GAME will be ignored) - */ - SET_SPEED , - /* Execute computation steps - * Data: XXX - */ - STEPS , - /* Set a view builder - * Data: XXX - */ - SET_VIEW , - /* Indicate that a view has been displayed - * Data: T_String - identifier of the view - */ - VIEW_DISPLAYED , - /* Send a query to the game - * Data: XXX - */ - QUERY , - /* Send a command to the game - * Data: XXX - */ - COMMAND -}; -M_LSHIFT_OP( T_StringBuilder , E_GameUIMessage ); - -/*----------------------------------------------------------------------------*/ - -/* Types of messages sent by the main loop to the UI */ -enum class E_GameLoopMessage { - /* Main loop exiting - * Data: none - */ - TERMINATED , - /* Progress information - * Data: T_ProgressInfo - */ - PROGRESS , - /* Operation completed - * Data: none - */ - DONE , - /* State changed - * Data: E_GameState - */ - STATE_CHANGED , - /* Indicate that a view is available - * Data: XXX - */ - VIEW_AVAILABLE , - /* Query response - * Data: XXX - */ - QUERY_RESPONSE , - /* Command execution - success - * Data: none - */ - COMMAND_OK , - /* Command execution - syntax error - * Data: XXX - */ - COMMAND_SYNTAX , - /* Command execution - error - * Data: XXX - */ - COMMAND_ERROR , -}; -M_LSHIFT_OP( T_StringBuilder , E_GameLoopMessage ); - -/*----------------------------------------------------------------------------*/ - -/* Types for message data */ -using T_GameUIMessageData = T_Union< - uint32_t , - T_String , - E_GameState - >; -using T_GameLoopMessageData = T_Union< - T_ProgressInfo , - E_GameState - >; - -/*----------------------------------------------------------------------------*/ - -/* Message direction */ -enum class E_MessageDirection { - FROM_UI_TO_GAME , - FROM_GAME_TO_UI -}; - -/* Message class template, can be used for both directions */ -template< - E_MessageDirection Direction , - typename EType = std::conditional_t< - Direction == E_MessageDirection::FROM_UI_TO_GAME , - E_GameUIMessage , E_GameLoopMessage > , - typename DType = std::conditional_t< - Direction == E_MessageDirection::FROM_UI_TO_GAME , - T_GameUIMessageData , T_GameLoopMessageData > -> -class T_GameMessage -{ - public: - using T_Type = EType; - using T_Data = DType; - - private: - using T_Self_ = T_GameMessage< Direction >; - T_Optional< T_Type > type_; - T_Optional< T_Data > data_; - - public: - constexpr T_GameMessage( ) noexcept; - constexpr T_GameMessage( T_Type type ) noexcept; - T_GameMessage( T_Type type , T_Data data ) noexcept; - T_GameMessage( T_Self_ const& ) = delete; - T_GameMessage( T_Self_&& other ) noexcept; - - T_Self_& operator =( T_Self_ const& ) = delete; - T_Self_& operator =( T_Self_&& other ) noexcept; - - constexpr bool hasMessage( ) const noexcept; - constexpr T_Type type( ) const noexcept; - - template< typename T > - constexpr T const& data( ) const; -}; - -/*----------------------------------------------------------------------------*/ - -using T_UIMessage = T_GameMessage< E_MessageDirection::FROM_UI_TO_GAME >; -using T_LoopMessage = T_GameMessage< E_MessageDirection::FROM_GAME_TO_UI >; - - -} // namespace lw -#endif // _H_LW_LIB_MESSAGES -#include diff --git a/include/ebcl/Mods.hh b/include/ebcl/Mods.hh deleted file mode 100644 index 88572b2..0000000 --- a/include/ebcl/Mods.hh +++ /dev/null @@ -1,247 +0,0 @@ -/******************************************************************************/ -/* MODDING SYSTEM *************************************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_MODS -#define _H_LW_LIB_MODS -#include -#include -namespace lw { - - -/*= MOD INFORMATION ==========================================================*/ - -/* Mod identifier (name + version) */ -struct T_ModIdentifier { - T_String name; - uint32_t version; // Main version number used for dependencies - - bool operator ==( T_ModIdentifier const& other ) const noexcept; - bool operator !=( T_ModIdentifier const& other ) const noexcept; - - int compare( T_ModIdentifier const& other ) const noexcept; -}; -M_CLASS_POINTERS( ModIdentifier ); -M_DECLARE_HASH( T_ModIdentifier ); -M_DECLARE_COMPARATOR( T_ModIdentifier ); -M_LSHIFT_OP( T_StringBuilder , T_ModIdentifier const& ); - -/* Types of mods */ -enum class E_ModType { - DATA , // This mod consists of data only - NATIVE , // This mod consists of native code - UI , // This mod is an user interface -}; - -/*----------------------------------------------------------------------------*/ - -/* Mod information record */ -struct T_ModInfo -{ - T_String path; - E_ModType type; - - /* Mod name, version and revision (the latter is for changes that don't - * affect the interface). - */ - T_ModIdentifier identifier; - uint32_t revision; - - /* Required library version number */ - uint32_t libVersion; - - /* List of dependencies */ - T_Array< T_ModIdentifier > modDeps; - - /* Is this mod an user interface mod? */ - bool isUserInterface( ) const noexcept; -}; -M_CLASS_POINTERS( ModInfo ); -M_LSHIFT_OP( T_StringBuilder , T_ModInfo const& ); - - -/*= MODS MANAGER CONFIGURATION ===============================================*/ - -/* Loading mode for a mod */ -enum class E_ModMode { - EXCLUDE , // Never load this mod - AUTO , // Load the most appropriate version of the mod - VERSION , // Load a specific version of the mod, fails - // if the mod in the specified version is not - // present - REQUIRE // Require that the specified mod be present - - // Note that both VERSION and REQUIRE can apply to an UI-specific mod; - // while the mod will not be loaded if the corresponding UI isn't, - // its presence will still be required. -}; - -/* Mods manager configuration */ -class T_ModsManagerConfiguration : public A_PrivateImplementation -{ - public: - T_ModsManagerConfiguration( ) noexcept; - - T_ModsManagerConfiguration( - T_ModsManagerConfiguration const& ) = delete; - T_ModsManagerConfiguration& operator =( - T_ModsManagerConfiguration const& ) = delete; - - T_ModsManagerConfiguration( - T_ModsManagerConfiguration&& ) noexcept; - T_ModsManagerConfiguration& operator =( - T_ModsManagerConfiguration&& other ) noexcept; - - // --------------------------------------------------------------------- - - /* Set a mod configuration entry */ - void setAuto( T_String const& name ) noexcept; - void setRequired( T_String const& name ) noexcept; - void setExcluded( T_String const& name ) noexcept; - void setVersion( T_String const& name , - uint32_t version ) noexcept; - void setVersion( T_String const& name , - uint32_t version , - uint32_t revision ) noexcept; - - /* Query mod configuration */ - T_Array< T_String > configured( ) const noexcept; - E_ModMode modeFor( T_String const& name ) const noexcept; - uint32_t requiredVersion( T_String const& name ) const noexcept; - T_Optional< uint32_t > requiredRevision( - T_String const& name ) const noexcept; - - // --------------------------------------------------------------------- - - /* Set or clear an UI preference */ - void setUIPreference( - T_String const& name , - int32_t weight ) noexcept; - void clearUIPreference( - T_String const& name ) noexcept; - - /* List UI preferences */ - T_Array< T_String > uiPreferences( ) const noexcept; - /* Get the preference for an UI */ - int32_t uiPreference( - T_String const& name ) const noexcept; - - // --------------------------------------------------------------------- - - /* Filter a list of mods using the configuration's exclusions and - * version limits. - */ - T_Array< RPC_ModInfo > filterMods( - T_Array< RPC_ModInfo > const& mods ) const noexcept; - /* Generate the list of required mods. This includes all mods that - * have been set as required, and all mods that have a version - * requirement. - */ - T_Array< T_String > requiredMods( ) const noexcept; - - // --------------------------------------------------------------------- - - /* Get a default configuration */ - static T_ModsManagerConfiguration DefaultConfiguration( ) noexcept; - - /* Get the parser's configuration used to load mods manager configuration */ - static T_SRDParserConfig GetParserConfig( ); -}; -M_CLASS_POINTERS( ModsManagerConfiguration ); - - -/*= MODS DEPENDENCY GRAPH ====================================================*/ - -class T_ModsDependencies : public A_PrivateImplementation -{ - public: - T_ModsDependencies( ) noexcept; - T_ModsDependencies( - T_Logger& logger , - T_Array< RPC_ModInfo > const& mods , - T_ModsManagerConfiguration const& config ) noexcept; - - T_ModsDependencies( - T_ModsDependencies const& other ) noexcept; - T_ModsDependencies& operator =( - T_ModsDependencies const& other ) noexcept; - - T_ModsDependencies( - T_ModsDependencies&& other ) noexcept; - T_ModsDependencies& operator =( - T_ModsDependencies&& other ) noexcept; - - friend M_DECLARE_SWAP( T_ModsDependencies ); - - // --------------------------------------------------------------------- - - bool resolved( ) const; - bool ambiguous( ) const; - T_Array< T_String > userInterfaces( ) const; - T_Array< RPC_ModInfo > const& commonMods( ) const; - T_Array< RPC_ModInfo >::RPC forUserInterface( - T_String const& name ) const; -}; -M_CLASS_POINTERS( ModsDependencies ); -M_DECLARE_SWAP( T_ModsDependencies ); - - -/*= MODS MANAGER =============================================================*/ - -/* Function type for a function that generates a feedback function used to - * update the initialisation progress when the mods are being initialised. - */ -using F_CreateInitUpdater = std::function< F_UpdateInitProgress( RPC_ModInfo ) >; - -class T_ModsManager : public A_PrivateImplementation -{ - public: - T_ModsManager( ) = delete; - T_ModsManager( T_ModsManager const& ) = delete; - T_ModsManager( T_ModsManager&& ) noexcept = delete; - - T_ModsManager( T_ModsManagerConfiguration&& config ) noexcept; - - // --------------------------------------------------------------------- - - /* Find available mods, load their descriptions */ - bool scanForMods( ); - /* Get the list of available mods */ - T_Array< RPC_ModInfo > availableMods( ) const noexcept; - - /* Resolve dependencies between mods using the configuration; - * returns true if there is a valid set of mods. - */ - bool resolveDependencies( ) noexcept; - - // --------------------------------------------------------------------- - - /* Pre-initialise common mods */ - bool preinitCommon( ) noexcept; - /* Pre-initialise UI mods and try to start the user interface. */ - OP_UserInterface preinitUIMods( - T_String const& ui ) noexcept; - /* Try to pre-initialise an UI mod. */ - OP_UserInterface preinitUIMods( ) noexcept; - - // --------------------------------------------------------------------- - - /* Get the amount of loaded mods */ - uint32_t modsCount( ) const noexcept; - /* Initialise the mods, sending progress updates along the way */ - bool initialise( - F_CreateInitUpdater const& fciu ) noexcept; - - // --------------------------------------------------------------------- - - /* Shutdown all initialised mods. */ - void shutdown( ) noexcept; - /* Unload all mods, calling post-shutdown routines if available */ - void unload( ) noexcept; -}; -M_CLASS_POINTERS( ModsManager ); - - -} // namespace lw -#endif // _H_LW_LIB_MODS -#include diff --git a/include/ebcl/Pointers.hh b/include/ebcl/Pointers.hh index 1cf6952..3f3b8b2 100644 --- a/include/ebcl/Pointers.hh +++ b/include/ebcl/Pointers.hh @@ -399,23 +399,23 @@ template< #define M_CLASS_POINTERS( NAME ) \ typedef T_ ## NAME* RP_ ## NAME; \ typedef T_ ## NAME const* RPC_ ## NAME; \ - typedef T_OwnPtr< T_ ## NAME > OP_ ## NAME; \ - typedef T_SharedPtr< T_ ## NAME > SP_ ## NAME; \ - typedef T_WeakPtr< T_ ## NAME > WP_ ## NAME + typedef ::ebcl::T_OwnPtr< T_ ## NAME > OP_ ## NAME; \ + typedef ::ebcl::T_SharedPtr< T_ ## NAME > SP_ ## NAME; \ + typedef ::ebcl::T_WeakPtr< T_ ## NAME > WP_ ## NAME #define M_ABSTRACT_POINTERS( NAME ) \ typedef A_ ## NAME* RP_ ## NAME; \ typedef A_ ## NAME const* RPC_ ## NAME; \ - typedef T_OwnPtr< A_ ## NAME > OP_ ## NAME; \ - typedef T_SharedPtr< A_ ## NAME > SP_ ## NAME; \ - typedef T_WeakPtr< A_ ## NAME > WP_ ## NAME + typedef ::ebcl::T_OwnPtr< A_ ## NAME > OP_ ## NAME; \ + typedef ::ebcl::T_SharedPtr< A_ ## NAME > SP_ ## NAME; \ + typedef ::ebcl::T_WeakPtr< A_ ## NAME > WP_ ## NAME #define M_TEMPLATE_POINTERS( NAME ) \ typedef NAME* RP; \ typedef NAME const* RPC; \ - typedef T_OwnPtr< NAME > OP; \ - typedef T_SharedPtr< NAME > SP; \ - typedef T_WeakPtr< NAME > WP + typedef ::ebcl::T_OwnPtr< NAME > OP; \ + typedef ::ebcl::T_SharedPtr< NAME > SP; \ + typedef ::ebcl::T_WeakPtr< NAME > WP } // namespace diff --git a/include/ebcl/SRDBinary.hh b/include/ebcl/SRDBinary.hh index 2fc8612..7185723 100644 --- a/include/ebcl/SRDBinary.hh +++ b/include/ebcl/SRDBinary.hh @@ -2,11 +2,11 @@ /* SRD - BINARY STORAGE *******************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_SRDBINARY -#define _H_LW_LIB_SRDBINARY -#include -#include -namespace lw { +#ifndef _H_EBCL_SRDBINARY +#define _H_EBCL_SRDBINARY +#include +#include +namespace ebcl { /*= WRITER ===================================================================*/ @@ -74,5 +74,5 @@ T_SRDList SRDBinaryReadFrom( T_String const& name , A_InputStream& input , bool } // namespace -#include -#endif // _H_LW_LIB_SRDBINARY +#include +#endif // _H_EBCL_SRDBINARY diff --git a/include/ebcl/SRDData.hh b/include/ebcl/SRDData.hh index 54fa63d..7ff86a6 100644 --- a/include/ebcl/SRDData.hh +++ b/include/ebcl/SRDData.hh @@ -2,12 +2,12 @@ /* SRD - DATA *****************************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_SRDDATA -#define _H_LW_LIB_SRDDATA -#include -#include -#include -namespace lw { +#ifndef _H_EBCL_SRDDATA +#define _H_EBCL_SRDDATA +#include +#include +#include +namespace ebcl { class T_Logger; @@ -206,9 +206,6 @@ class X_SRDErrors : public std::exception const T_SRDErrors errors; X_SRDErrors( T_SRDErrors const& errors ); char const * what( ) const noexcept override; -#ifndef LW_MINLIB - void log( T_Logger& logger ) const; -#endif // LW_MINLIB }; @@ -357,5 +354,5 @@ extern template class T_Array< T_SRDToken >; } // namespace -#include -#endif // _H_LW_LIB_SRDDATA +#include +#endif // _H_EBCL_SRDDATA diff --git a/include/ebcl/SRDDefinitions.hh b/include/ebcl/SRDDefinitions.hh index aa70321..afc9c3c 100644 --- a/include/ebcl/SRDDefinitions.hh +++ b/include/ebcl/SRDDefinitions.hh @@ -2,11 +2,11 @@ /* SRD - PARSER DEFINITIONS ***************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_SRDDEFINITIONS -#define _H_LW_LIB_SRDDEFINITIONS -#include -#include -namespace lw { +#ifndef _H_EBCL_SRDDEFINITIONS +#define _H_EBCL_SRDDEFINITIONS +#include +#include +namespace ebcl { /*= DEFINITION DATA ==========================================================*/ @@ -317,5 +317,5 @@ T_SRDInputRule::T_SetContextExecutor OnExit( F_SRDHandler f ); } // namespace -#include -#endif // _H_LW_LIB_SRDDEFINITIONS +#include +#endif // _H_EBCL_SRDDEFINITIONS diff --git a/include/ebcl/SRDIO.hh b/include/ebcl/SRDIO.hh index d2b02ca..3c53dfd 100644 --- a/include/ebcl/SRDIO.hh +++ b/include/ebcl/SRDIO.hh @@ -2,10 +2,10 @@ /* SRD - INPUT AND OUTPUT *****************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_SRDIO -#define _H_LW_LIB_SRDIO -#include -namespace lw { +#ifndef _H_EBCL_SRDIO +#define _H_EBCL_SRDIO +#include +namespace ebcl { /*= INPUT / OUTPUT ABSTRACTIONS ==============================================*/ @@ -183,5 +183,5 @@ M_CLASS_POINTERS( SRDWriterTarget ); } // namespace -#include -#endif // _H_LW_LIB_SRDIO +#include +#endif // _H_EBCL_SRDIO diff --git a/include/ebcl/SRDPPCommands.hh b/include/ebcl/SRDPPCommands.hh deleted file mode 100644 index c66beb8..0000000 --- a/include/ebcl/SRDPPCommands.hh +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************/ -/* SRD - PREPROCESSOR COMMANDS ************************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_SRDPPCOMMANDS -#define _H_LW_LIB_SRDPPCOMMANDS -#include -namespace lw { - - -M_SRDPP_COMMAND_DECL( Add ); M_SRDPP_COMMAND_INIT( Add , "add" ); -M_SRDPP_COMMAND_DECL( And ); M_SRDPP_COMMAND_INIT( And , "and" ); - -M_SRDPP_COMMAND_DECL( Bless ); M_SRDPP_COMMAND_INIT( Bless , "bless" ); -M_SRDPP_COMMAND_DECL( Break ); M_SRDPP_COMMAND_INIT( Break , "break" ); -M_SRDPP_COMMAND_DECL( BwAnd ); M_SRDPP_COMMAND_INIT( BwAnd , "bw-and" ); -M_SRDPP_COMMAND_DECL( BwNot ); M_SRDPP_COMMAND_INIT( BwNot , "bw-not" ); -M_SRDPP_COMMAND_DECL( BwOr ); M_SRDPP_COMMAND_INIT( BwOr , "bw-or" ); -M_SRDPP_COMMAND_DECL( BwXor ); M_SRDPP_COMMAND_INIT( BwXor , "bw-xor" ); - -M_SRDPP_COMMAND_DECL( Call ); M_SRDPP_COMMAND_INIT( Call , "call" ); -M_SRDPP_COMMAND_DECL( CastString ); M_SRDPP_COMMAND_INIT( CastString , "to-string" ); -M_SRDPP_COMMAND_DECL( CastWord ); M_SRDPP_COMMAND_INIT( CastWord , "to-word" ); -M_SRDPP_COMMAND_DECL( CastInt ); M_SRDPP_COMMAND_INIT( CastInt , "to-integer" ); -M_SRDPP_COMMAND_DECL( CastLong ); M_SRDPP_COMMAND_INIT( CastLong , "to-long" ); -M_SRDPP_COMMAND_DECL( CastBestInt ); M_SRDPP_COMMAND_INIT( CastBestInt , "to-best-integer" ); -M_SRDPP_COMMAND_DECL( CastReal ); M_SRDPP_COMMAND_INIT( CastReal , "to-real" ); -M_SRDPP_COMMAND_DECL( CastVar ); M_SRDPP_COMMAND_INIT( CastVar , "to-variable" ); -M_SRDPP_COMMAND_DECL( CastList ); M_SRDPP_COMMAND_INIT( CastList , "to-list" ); -M_SRDPP_COMMAND_DECL( ClearScope ); M_SRDPP_COMMAND_INIT_N( ClearScope , "clear-scope" , 0 ); -M_SRDPP_COMMAND_DECL( Cmp ); M_SRDPP_COMMAND_INIT( Cmp , "cmp" ); -M_SRDPP_COMMAND_DECL( CmpEq ); M_SRDPP_COMMAND_INIT( CmpEq , "eq" ); -M_SRDPP_COMMAND_DECL( CmpNe ); M_SRDPP_COMMAND_INIT( CmpNe , "ne" ); -M_SRDPP_COMMAND_DECL( CmpLt ); M_SRDPP_COMMAND_INIT( CmpLt , "lt" ); -M_SRDPP_COMMAND_DECL( CmpGt ); M_SRDPP_COMMAND_INIT( CmpGt , "gt" ); -M_SRDPP_COMMAND_DECL( CmpLe ); M_SRDPP_COMMAND_INIT( CmpLe , "le" ); -M_SRDPP_COMMAND_DECL( CmpGe ); M_SRDPP_COMMAND_INIT( CmpGe , "ge" ); -M_SRDPP_COMMAND_DECL( Concat ); M_SRDPP_COMMAND_INIT( Concat , "concat" ); - -M_SRDPP_COMMAND_DECL( Div ); M_SRDPP_COMMAND_INIT( Div , "div" ); - -M_SRDPP_COMMAND_DECL( EndsWith ); M_SRDPP_COMMAND_INIT( EndsWith , "ends-with" ); -M_SRDPP_COMMAND_DECL( Eval ); M_SRDPP_COMMAND_INIT( Eval , "eval" ); -M_SRDPP_COMMAND_DECL( Error ); M_SRDPP_COMMAND_INIT( Error , "error" ); - -M_SRDPP_COMMAND_DECL( FromSource ); M_SRDPP_COMMAND_INIT( FromSource , "from-source" ); -M_SRDPP_COMMAND_DECL( FromSRB ); M_SRDPP_COMMAND_INIT( FromSRB , "from-srb" ); - -M_SRDPP_COMMAND_DECL( Get ); M_SRDPP_COMMAND_INIT( Get , "get" ); - -M_SRDPP_COMMAND_DECL( If ); M_SRDPP_COMMAND_INIT_N( If , "if" , 1 ); -M_SRDPP_COMMAND_DECL( Ignore ); M_SRDPP_COMMAND_INIT_N( Ignore , "ignore" , 0 ); -M_SRDPP_COMMAND_DECL( IsBlessed ); M_SRDPP_COMMAND_INIT( IsBlessed , "is-blessed" ); -M_SRDPP_COMMAND_DECL( IsMacro ); M_SRDPP_COMMAND_INIT( IsMacro , "is-macro" ); -M_SRDPP_COMMAND_DECL( IsSet ); M_SRDPP_COMMAND_INIT( IsSet , "is-set" ); - -M_SRDPP_COMMAND_DECL( Length ); M_SRDPP_COMMAND_INIT( Length , "length" ); -M_SRDPP_COMMAND_DECL( ListMacros ); M_SRDPP_COMMAND_INIT_N( ListMacros , "ls-macros" , 0 ); -M_SRDPP_COMMAND_DECL( ListVariables ); M_SRDPP_COMMAND_INIT_N( ListVariables , "ls-variables" , 0 ); - -M_SRDPP_COMMAND_DECL( Mod ); M_SRDPP_COMMAND_INIT( Mod , "mod" ); -M_SRDPP_COMMAND_DECL( Mul ); M_SRDPP_COMMAND_INIT( Mul , "mul" ); - -M_SRDPP_COMMAND_DECL( Neg ); M_SRDPP_COMMAND_INIT( Neg , "neg" ); -M_SRDPP_COMMAND_DECL( Not ); M_SRDPP_COMMAND_INIT( Not , "not" ); - -M_SRDPP_COMMAND_DECL( Or ); M_SRDPP_COMMAND_INIT( Or , "or" ); -M_SRDPP_COMMAND_DECL( Output ); M_SRDPP_COMMAND_INIT( Output , "output" ); - -M_SRDPP_COMMAND_DECL( Raw ); M_SRDPP_COMMAND_INIT_N( Raw , "raw" , 0 ); -M_SRDPP_COMMAND_DECL( Rethrow ); M_SRDPP_COMMAND_INIT( Rethrow , "rethrow" ); - -M_SRDPP_COMMAND_DECL( Scope ); M_SRDPP_COMMAND_INIT_N( Scope , "scope" , 0 ); -M_SRDPP_COMMAND_DECL( Set ); M_SRDPP_COMMAND_INIT( Set , "set" ); -M_SRDPP_COMMAND_DECL( SetMacro ); M_SRDPP_COMMAND_INIT( SetMacro , "set-macro" ); -M_SRDPP_COMMAND_DECL( StartsWith ); M_SRDPP_COMMAND_INIT( StartsWith , "starts-with" ); -M_SRDPP_COMMAND_DECL( StrFind ); M_SRDPP_COMMAND_INIT( StrFind , "str-find" ); -M_SRDPP_COMMAND_DECL( StrSplit ); M_SRDPP_COMMAND_INIT( StrSplit , "str-split" ); -M_SRDPP_COMMAND_DECL( Sub ); M_SRDPP_COMMAND_INIT( Sub , "sub" ); -M_SRDPP_COMMAND_DECL( Substr ); M_SRDPP_COMMAND_INIT( Substr , "substr" ); - -M_SRDPP_COMMAND_DECL( ToSource ); M_SRDPP_COMMAND_INIT( ToSource , "to-source" ); -M_SRDPP_COMMAND_DECL( Try ); M_SRDPP_COMMAND_INIT_N( Try , "try" , 0 ); -M_SRDPP_COMMAND_DECL( TypeOf ); M_SRDPP_COMMAND_INIT( TypeOf , "type-of" ); - -M_SRDPP_COMMAND_DECL( Unset ); M_SRDPP_COMMAND_INIT( Unset , "unset" ); -M_SRDPP_COMMAND_DECL( UnsetMacro ); M_SRDPP_COMMAND_INIT( UnsetMacro , "unset-macro" ); -M_SRDPP_COMMAND_DECL( Unwrap ); M_SRDPP_COMMAND_INIT( Unwrap , "unwrap" ); - -M_SRDPP_COMMAND_DECL_OBJ( VFSList , T_VFS& , vfs_ ); -M_SRDPP_COMMAND_INIT_OBJ( VFSList , "vfs-list" , T_VFS& , vfs_ ); -M_SRDPP_COMMAND_DECL_OBJ( VFSLoad , T_VFS& , vfs_ ); -M_SRDPP_COMMAND_INIT_OBJ( VFSLoad , "vfs-load" , T_VFS& , vfs_ ); -M_SRDPP_COMMAND_DECL_OBJ( VFSType , T_VFS& , vfs_ ); -M_SRDPP_COMMAND_INIT_OBJ( VFSType , "vfs-type" , T_VFS& , vfs_ ); - -M_SRDPP_COMMAND_DECL( Xor ); M_SRDPP_COMMAND_INIT( Xor , "xor" ); - - -} // namespace lw -#endif // _H_LW_LIB_SRDPPCOMMANDS diff --git a/include/ebcl/SRDParser.hh b/include/ebcl/SRDParser.hh index 6a3d037..4cbd08c 100644 --- a/include/ebcl/SRDParser.hh +++ b/include/ebcl/SRDParser.hh @@ -1,11 +1,12 @@ /******************************************************************************/ -/* SRD PARSER AND PREPROCESSOR ************************************************/ +/* SRD PARSER *****************************************************************/ /******************************************************************************/ -#pragma once -#include -#include -namespace lw { +#ifndef _H_EBCL_SRDPARSER +#define _H_EBCL_SRDPARSER +#include +#include +namespace ebcl { // T_SRDParserData - Run-time data passed to the handlers when parsing @@ -88,3 +89,4 @@ inline T const& T_SRDParser::getData( ) const } // namespace +#endif // _H_EBCL_SRDPARSER diff --git a/include/ebcl/SRDParserConfig.hh b/include/ebcl/SRDParserConfig.hh index 3e55026..43c3f1b 100644 --- a/include/ebcl/SRDParserConfig.hh +++ b/include/ebcl/SRDParserConfig.hh @@ -2,11 +2,11 @@ /* SRD - PARSER CONFIGURATION *************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_SRDPARSERCONFIG -#define _H_LW_LIB_SRDPARSERCONFIG -#include -#include -namespace lw { +#ifndef _H_EBCL_SRDPARSERCONFIG +#define _H_EBCL_SRDPARSERCONFIG +#include +#include +namespace ebcl { /*= PROCESSED PARSER CONFIGURATION ===========================================*/ @@ -95,5 +95,5 @@ class X_SRDParserConfig : public std::exception } // namespace -#include -#endif // _H_LW_LIB_SRDPARSERCONFIG +#include +#endif // _H_EBCL_SRDPARSERCONFIG diff --git a/include/ebcl/SRDText.hh b/include/ebcl/SRDText.hh index ac22677..2b307f8 100644 --- a/include/ebcl/SRDText.hh +++ b/include/ebcl/SRDText.hh @@ -2,10 +2,10 @@ /* SRD - TEXT STORAGE *********************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_SRDTEXT -#define _H_LW_LIB_SRDTEXT -#include -namespace lw { +#ifndef _H_EBCL_SRDTEXT +#define _H_EBCL_SRDTEXT +#include +namespace ebcl { /*= READER ===================================================================*/ @@ -89,5 +89,5 @@ void SRDWriteAsText( A_OutputStream& output , T_SRDList const& data ); } // namespace -#include -#endif // _H_LW_LIB_SRDTEXT +#include +#endif // _H_EBCL_SRDTEXT diff --git a/include/ebcl/Version.hh b/include/ebcl/Version.hh deleted file mode 100644 index 9f19f80..0000000 --- a/include/ebcl/Version.hh +++ /dev/null @@ -1,19 +0,0 @@ -/******************************************************************************/ -/* VERSION NUMBERS ************************************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_VERSION -#define _H_LW_LIB_VERSION -#include -namespace lw { - - -static constexpr inline uint32_t LibVersion( ) - { return 0; } - -static constexpr inline uint32_t LibRevision( ) - { return 0; } - - -} -#endif // _H_LW_LIB_VERSION diff --git a/include/ebcl/Version.hh.in b/include/ebcl/Version.hh.in deleted file mode 100644 index 06b6645..0000000 --- a/include/ebcl/Version.hh.in +++ /dev/null @@ -1,19 +0,0 @@ -/******************************************************************************/ -/* VERSION NUMBERS ************************************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_VERSION -#define _H_LW_LIB_VERSION -#include -namespace lw { - - -static constexpr inline uint32_t LibVersion( ) - { return __VERSION__; } - -static constexpr inline uint32_t LibRevision( ) - { return __REVISION__; } - - -} -#endif // _H_LW_LIB_VERSION diff --git a/include/ebcl/inline/DynLib.hh b/include/ebcl/inline/DynLib.hh index 81d61da..2e7baca 100644 --- a/include/ebcl/inline/DynLib.hh +++ b/include/ebcl/inline/DynLib.hh @@ -2,11 +2,11 @@ /* DYNAMIC LIBRARIES - INLINE CODE ********************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_DYNLIB -#define _H_LW_LIB_INLINE_DYNLIB +#ifndef _H_EBCL_INLINE_DYNLIB +#define _H_EBCL_INLINE_DYNLIB -#include -namespace lw { +#include +namespace ebcl { /*= T_DynLib =================================================================*/ @@ -27,4 +27,4 @@ inline std::function< T > T_DynLib::getFunction( } -#endif // _H_LW_LIB_INLINE_DYNLIB +#endif // _H_EBCL_INLINE_DYNLIB diff --git a/include/ebcl/inline/Messages.hh b/include/ebcl/inline/Messages.hh deleted file mode 100644 index a77a05f..0000000 --- a/include/ebcl/inline/Messages.hh +++ /dev/null @@ -1,154 +0,0 @@ -/******************************************************************************/ -/* UI<=>GAME MESSAGES - INLINE CODE *******************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_INLINE_MESSAGES -#define _H_LW_LIB_INLINE_MESSAGES -#include -namespace lw { - - -/*= T_ProgressInfoPart =======================================================*/ - -inline T_ProgressInfoPart::T_ProgressInfoPart( T_String text , - uint32_t progress , uint32_t total ) noexcept - : text_( std::move( text ) ) , progress_( progress ) , total_( total ) -{ } - -inline T_ProgressInfoPart::T_ProgressInfoPart( T_ProgressInfoPart&& other ) noexcept - : text_( std::move( other.text_ ) ) , progress_( other.progress_ ) , - total_( other.total_ ) -{ } - -inline T_ProgressInfoPart::T_ProgressInfoPart( T_ProgressInfoPart const& other ) - : text_( other.text_ ) , progress_( other.progress_ ) , total_( other.total_ ) -{ } - -/*----------------------------------------------------------------------------*/ - -inline T_String const& T_ProgressInfoPart::text( ) const noexcept -{ - return text_; -} - -inline uint32_t T_ProgressInfoPart::progress( ) const noexcept -{ - return progress_; -} - -inline uint32_t T_ProgressInfoPart::total( ) const noexcept -{ - return total_; -} - - -/*= T_ProgressInfo ===========================================================*/ - -inline T_ProgressInfo::T_ProgressInfo( T_String text , uint32_t progress , uint32_t total ) noexcept - : main_( std::move( text ) , progress , total ) , sub_( ) -{ } - -inline T_ProgressInfo::T_ProgressInfo( T_ProgressInfoPart main ) noexcept - : main_( std::move( main ) ) -{ } - -inline T_ProgressInfo::T_ProgressInfo( - T_ProgressInfoPart main , - T_ProgressInfoPart sub ) noexcept - : main_( std::move( main ) ) , - sub_( std::move( sub ) ) -{ } - -inline T_ProgressInfo::T_ProgressInfo( T_ProgressInfoPart main , - T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept - : main_( std::move( main ) ) , - sub_( T_ProgressInfoPart{ std::move( sText ) , sProgress , sTotal } ) -{ } - -inline T_ProgressInfo::T_ProgressInfo( T_String text , uint32_t progress , uint32_t total , - T_String sText , uint32_t sProgress , uint32_t sTotal ) noexcept - : main_( std::move( text ) , progress , total ) , - sub_( T_ProgressInfoPart{ std::move( sText ) , sProgress , sTotal } ) -{ } - -inline T_ProgressInfo::T_ProgressInfo( T_ProgressInfo&& other ) noexcept - : main_( std::move( other.main_ ) ) , sub_( std::move( other.sub_ ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -inline T_ProgressInfoPart const& T_ProgressInfo::main( ) const noexcept -{ - return main_; -} - -inline bool T_ProgressInfo::hasSub( ) const noexcept -{ - return sub_.present( ); -} - -inline T_ProgressInfoPart const& T_ProgressInfo::sub( ) const -{ - return (T_ProgressInfoPart const&) sub_; -} - - -/*= T_GameMessage ============================================================*/ - -template< E_MessageDirection D , typename MT , typename MD > -inline constexpr T_GameMessage< D , MT , MD >::T_GameMessage( ) noexcept - : type_( ) , data_( ) -{ } - -template< E_MessageDirection D , typename MT , typename MD > -inline constexpr T_GameMessage< D , MT , MD >::T_GameMessage( - T_Type type ) noexcept - : type_( type ) , data_( ) -{ } - -template< E_MessageDirection D , typename MT , typename MD > -inline T_GameMessage< D , MT , MD >::T_GameMessage( - T_Type type , - T_Data data ) noexcept - : type_( type ) , data_( data ) -{ } - -template< E_MessageDirection D , typename MT , typename MD > -inline T_GameMessage< D , MT , MD >::T_GameMessage( - T_Self_&& other ) noexcept - : type_( other.type_ ) , data_( std::move( other.data_ ) ) -{ } - -template< E_MessageDirection D , typename MT , typename MD > -inline T_GameMessage< D >& T_GameMessage< D , MT , MD >::operator =( - T_Self_&& other ) noexcept -{ - type_ = other.type_; - data_ = std::move( other.data_ ); - return *this; -} - -/*----------------------------------------------------------------------------*/ - -template< E_MessageDirection D , typename MT , typename MD > -inline constexpr bool T_GameMessage< D , MT , MD >::hasMessage( ) const noexcept -{ - return type_.present( ); -} - -template< E_MessageDirection D , typename MT , typename MD > -inline constexpr MT T_GameMessage< D , MT , MD >::type( ) const noexcept -{ - return type_; -} - -template< E_MessageDirection D , typename MT , typename MD > -template< typename T > -constexpr T const& T_GameMessage< D , MT , MD >::data( ) const -{ - return (T const&)( (MD const&) data_ ); -} - - -} // namespace lw -#endif // _H_LW_LIB_INLINE_MESSAGES diff --git a/include/ebcl/inline/Mods.hh b/include/ebcl/inline/Mods.hh deleted file mode 100644 index 2e16087..0000000 --- a/include/ebcl/inline/Mods.hh +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************/ -/* MODDING SYSTEM - INLINE CODE ***********************************************/ -/******************************************************************************/ - -#ifndef _H_LW_LIB_INLINE_MODS -#define _H_LW_LIB_INLINE_MODS -#include -namespace lw { - - -/*= T_ModIdentifier ==========================================================*/ - -inline bool T_ModIdentifier::operator ==( - T_ModIdentifier const& other ) const noexcept -{ - return &other == this || ( name == other.name - && version == other.version ); -} - -inline bool T_ModIdentifier::operator !=( - T_ModIdentifier const& other ) const noexcept -{ - return &other != this && ( name != other.name - || version != other.version ); -} - -inline M_DEFINE_HASH( T_ModIdentifier ) -{ - return ComputeHash( item.name ) * 47 + item.version; -} - -inline M_DEFINE_COMPARATOR( T_ModIdentifier ) -{ - return a.compare( b ); -} - -inline M_LSHIFT_OP( T_StringBuilder , T_ModIdentifier const& ) -{ - obj << value.name << ':' << value.version; - return obj; -} - - -/*= T_ModInfo ================================================================*/ - -inline bool T_ModInfo::isUserInterface( ) const noexcept -{ - return type == E_ModType::UI; -} - -inline M_LSHIFT_OP( T_StringBuilder , T_ModInfo const& ) -{ - obj << value.identifier << '.' << value.revision; - return obj; -} - - -} -#endif // _H_LW_LIB_INLINE_MODS diff --git a/include/ebcl/inline/SRDBinary.hh b/include/ebcl/inline/SRDBinary.hh index cf25bad..a5e218f 100644 --- a/include/ebcl/inline/SRDBinary.hh +++ b/include/ebcl/inline/SRDBinary.hh @@ -2,10 +2,10 @@ /* SRD - BINARY STORAGE - INLINE CODE *****************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_SRDBINARY -#define _H_LW_LIB_INLINE_SRDBINARY -#include -namespace lw { +#ifndef _H_EBCL_INLINE_SRDBINARY +#define _H_EBCL_INLINE_SRDBINARY +#include +namespace ebcl { inline void SRDBinaryWriteTo( A_OutputStream& output , T_SRDList const& data ) @@ -30,4 +30,4 @@ inline T_SRDList SRDBinaryReadFrom( T_String const& name , A_InputStream& input } // namespace -#endif // _H_LW_LIB_INLINE_SRDBINARY +#endif // _H_EBCL_INLINE_SRDBINARY diff --git a/include/ebcl/inline/SRDData.hh b/include/ebcl/inline/SRDData.hh index 6bf0150..b5eadab 100644 --- a/include/ebcl/inline/SRDData.hh +++ b/include/ebcl/inline/SRDData.hh @@ -2,10 +2,10 @@ /* SRD - DATA - INLINE CODE ***************************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_SRDDATA -#define _H_LW_LIB_INLINE_SRDDATA -#include -namespace lw { +#ifndef _H_EBCL_INLINE_SRDDATA +#define _H_EBCL_INLINE_SRDDATA +#include +namespace ebcl { /*= T_SRDLocationChaining ====================================================*/ @@ -435,4 +435,4 @@ inline T_SRDLocation const& T_SRDToken::location( ) const noexcept } // namespace -#endif // _H_LW_LIB_INLINE_SRDDATA +#endif // _H_EBCL_INLINE_SRDDATA diff --git a/include/ebcl/inline/SRDDefinitions.hh b/include/ebcl/inline/SRDDefinitions.hh index 0c94d56..e8dc3d9 100644 --- a/include/ebcl/inline/SRDDefinitions.hh +++ b/include/ebcl/inline/SRDDefinitions.hh @@ -2,10 +2,10 @@ /* SRD - PARSER DEFINITIONS - INLINE CODE *************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_SRDDEFINITIONS -#define _H_LW_LIB_INLINE_SRDDEFINITIONS -#include -namespace lw { +#ifndef _H_EBCL_INLINE_SRDDEFINITIONS +#define _H_EBCL_INLINE_SRDDEFINITIONS +#include +namespace ebcl { /*= T_SRDEnum ================================================================*/ @@ -522,4 +522,4 @@ inline T_SRDInputRule::T_SetContextExecutor OnExit( F_SRDHandler f ) } // namespace -#endif // _H_LW_LIB_INLINE_SRDDEFINITIONS +#endif // _H_EBCL_INLINE_SRDDEFINITIONS diff --git a/include/ebcl/inline/SRDIO.hh b/include/ebcl/inline/SRDIO.hh index 55a1c69..933317a 100644 --- a/include/ebcl/inline/SRDIO.hh +++ b/include/ebcl/inline/SRDIO.hh @@ -2,10 +2,10 @@ /* SRD - INPUT AND OUTPUT - INLINE CODE ***************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_SRDIO -#define _H_LW_LIB_INLINE_SRDIO -#include -namespace lw { +#ifndef _H_EBCL_INLINE_SRDIO +#define _H_EBCL_INLINE_SRDIO +#include +namespace ebcl { /*= A_SRDWriter ==============================================================*/ @@ -77,4 +77,4 @@ inline bool T_SRDMemoryTarget::complete( ) const } // namespace -#endif // _H_LW_LIB_INLINE_SRDIO +#endif // _H_EBCL_INLINE_SRDIO diff --git a/include/ebcl/inline/SRDParserConfig.hh b/include/ebcl/inline/SRDParserConfig.hh index 58710ce..da11d5c 100644 --- a/include/ebcl/inline/SRDParserConfig.hh +++ b/include/ebcl/inline/SRDParserConfig.hh @@ -2,10 +2,10 @@ /* SRD - PARSER CONFIGURATION - INLINE CODE ***********************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_SRDPARSERCONFIG -#define _H_LW_LIB_INLINE_SRDPARSERCONFIG -#include -namespace lw { +#ifndef _H_EBCL_INLINE_SRDPARSERCONFIG +#define _H_EBCL_INLINE_SRDPARSERCONFIG +#include +namespace ebcl { /*= T_SRDTransition ==========================================================*/ @@ -30,4 +30,4 @@ inline T_Optional< uint32_t > T_SRDParserConfig::enumValue( } // namespace -#endif // _H_LW_LIB_INLINE_SRDPARSERCONFIG +#endif // _H_EBCL_INLINE_SRDPARSERCONFIG diff --git a/include/ebcl/inline/SRDText.hh b/include/ebcl/inline/SRDText.hh index 2ba0bfb..fb5b85d 100644 --- a/include/ebcl/inline/SRDText.hh +++ b/include/ebcl/inline/SRDText.hh @@ -2,10 +2,10 @@ /* SRD - TEXT STORAGE - INLINE CODE *******************************************/ /******************************************************************************/ -#ifndef _H_LW_LIB_INLINE_SRDTEXT -#define _H_LW_LIB_INLINE_SRDTEXT -#include -namespace lw { +#ifndef _H_EBCL_INLINE_SRDTEXT +#define _H_EBCL_INLINE_SRDTEXT +#include +namespace ebcl { inline void SRDWriteAsText( A_OutputStream& output , T_SRDList const& data ) @@ -22,4 +22,4 @@ inline T_SRDTextReader::T_SRDTextReader( A_SRDReaderTarget& target ) } // namespace -#endif // _H_LW_LIB_INLINE_SRDTEXT +#endif // _H_EBCL_INLINE_SRDTEXT diff --git a/src/Console-Unix.hh b/src/Console-Unix.hh deleted file mode 100644 index db05496..0000000 --- a/src/Console-Unix.hh +++ /dev/null @@ -1,667 +0,0 @@ -/******************************************************************************/ -/* CONSOLE SUPPORT - UNIX IMPLEMENTATION **************************************/ -/******************************************************************************/ - -#include -#include -#include -#include - - -namespace { - -// List of unsupported terminals -char const* const BadTerminals_[] = { - "dumb" , "cons25" , "emacs" , - nullptr -}; - -// Extended input sequences -char const* const InputSequences_[] = { - "A" , // Up - "B" , // Down - "C" , // Right - "D" , // Left - "H" , // Home - "F" , // End - "3~" , // Delete - "1;5C" , // C-Right - "1;5D" , // C-Left - "15~" , // F5 - "17~" , // F6 - "18~" , // F7 - "19~" , // F8 - "20~" , // F9 - "21~" , // F10 - "23~" , // F11 - "24~" , // F12 - "1;2P" , // S-F1 - "1;2Q" , // S-F2 - "1;2R" , // S-F3 - "1;2S" , // S-F4 - "15;2~" , // S-F5 - "17;2~" , // S-F6 - "18;2~" , // S-F7 - "19;2~" , // S-F8 - "20;2~" , // S-F9 - "21;2~" , // S-F10 - "23;2~" , // S-F11 - "24;2~" , // S-F12 - "1;5P" , // C-F1 - "1;5Q" , // C-F2 - "1;5R" , // C-F3 - "1;5S" , // C-F4 - "15;5~" , // C-F5 - "17;5~" , // C-F6 - "18;5~" , // C-F7 - "19;5~" , // C-F8 - "20;5~" , // C-F9 - "21;5~" , // C-F10 - "23;5~" , // C-F11 - "24;5~" , // C-F12 - "1;6P" , // C-S-F1 - "1;6Q" , // C-S-F2 - "1;6R" , // C-S-F3 - "1;6S" , // C-S-F4 - "15;6~" , // C-S-F5 - "17;6~" , // C-S-F6 - "18;6~" , // C-S-F7 - "19;6~" , // C-S-F8 - "20;6~" , // C-S-F9 - "21;6~" , // C-S-F10 - "23;6~" , // C-S-F11 - "24;6~" , // C-S-F12 - nullptr -}; -const lw::E_ConsoleKey InputKeys_[] = { - lw::E_ConsoleKey::UP , - lw::E_ConsoleKey::DOWN , - lw::E_ConsoleKey::RIGHT , - lw::E_ConsoleKey::LEFT , - lw::E_ConsoleKey::HOME , - lw::E_ConsoleKey::END , - lw::E_ConsoleKey::DELETE , - lw::E_ConsoleKey::WNEXT , - lw::E_ConsoleKey::WPREV , - lw::E_ConsoleKey::F5 , - lw::E_ConsoleKey::F6 , - lw::E_ConsoleKey::F7 , - lw::E_ConsoleKey::F8 , - lw::E_ConsoleKey::F9 , - lw::E_ConsoleKey::F10 , - lw::E_ConsoleKey::F11 , - lw::E_ConsoleKey::F12 , - lw::E_ConsoleKey::S_F1 , - lw::E_ConsoleKey::S_F2 , - lw::E_ConsoleKey::S_F3 , - lw::E_ConsoleKey::S_F4 , - lw::E_ConsoleKey::S_F5 , - lw::E_ConsoleKey::S_F6 , - lw::E_ConsoleKey::S_F7 , - lw::E_ConsoleKey::S_F8 , - lw::E_ConsoleKey::S_F9 , - lw::E_ConsoleKey::S_F10 , - lw::E_ConsoleKey::S_F11 , - lw::E_ConsoleKey::S_F12 , - lw::E_ConsoleKey::C_F1 , - lw::E_ConsoleKey::C_F2 , - lw::E_ConsoleKey::C_F3 , - lw::E_ConsoleKey::C_F4 , - lw::E_ConsoleKey::C_F5 , - lw::E_ConsoleKey::C_F6 , - lw::E_ConsoleKey::C_F7 , - lw::E_ConsoleKey::C_F8 , - lw::E_ConsoleKey::C_F9 , - lw::E_ConsoleKey::C_F10 , - lw::E_ConsoleKey::C_F11 , - lw::E_ConsoleKey::C_F12 , - lw::E_ConsoleKey::CS_F1 , - lw::E_ConsoleKey::CS_F2 , - lw::E_ConsoleKey::CS_F3 , - lw::E_ConsoleKey::CS_F4 , - lw::E_ConsoleKey::CS_F5 , - lw::E_ConsoleKey::CS_F6 , - lw::E_ConsoleKey::CS_F7 , - lw::E_ConsoleKey::CS_F8 , - lw::E_ConsoleKey::CS_F9 , - lw::E_ConsoleKey::CS_F10 , - lw::E_ConsoleKey::CS_F11 , - lw::E_ConsoleKey::CS_F12 , -}; - -// Various control codes -const char CCGetTermSizeStart_[] = "\033[s\033[99999C\033[99999A"; -const char CCGetTermSizeEnd_[] = "\033[u"; -const char CCGetCursorPos_[] = "\033[6n"; -const char CCClearScreen_[] = "\033[H\033[2J"; -const char CCNextLine_[] = "\n\033[99999D\033[K"; -const char CCClearLine_[] = "\033[99999D\033[K"; -const char CCClearLineUp_[] = "\033[99999D\033[K\033[A"; - -// Are we running in an unsupported terminal? -inline bool IsBadTerminal_( ) -{ - char const* const t( getenv( "TERM" ) ); - if ( t == nullptr ) { - return true; - } - for ( auto i = 0 ; BadTerminals_[ i ] ; i ++ ) { - if ( !strcasecmp( t , BadTerminals_[ i ] ) ) { - return true; - } - } - return false; -} - -/*----------------------------------------------------------------------------*/ - -class T_ConsoleImpl_ -{ - private: - bool ok_; - termios initialTerm_; - lw::E_ConsoleInteractionMode mode_; - bool failed_; - bool interrupted_; - - int sizePolling_; - uint32_t rows_ , cols_; - - lw::T_StringBuilder styleSeq_; - uint8_t keyBuf_[ 16 ]; - uint32_t kbPos_; - - public: - T_ConsoleImpl_( ); - ~T_ConsoleImpl_( ); - - bool initConsole( ); - void shutdownConsole( ); - bool failed( ) const; - - bool resized( uint32_t& rows , uint32_t& cols ) const; - bool getTerminalSize( uint32_t& rows , uint32_t& cols ); - bool getCursorPosition( uint32_t& column , uint32_t& row ); - - bool readKey( lw::E_ConsoleKey& key , uint32_t& character ); - - bool clearScreen( ); - void setTextStyle( uint8_t style , lw::T_TextColor color ); - void printCharacter( lw::T_Character c ); - void nextLine( ); - void clearLine( ); - void clearLines( uint32_t count ); - void moveCursor( int32_t x , int32_t y ); - - private: - bool initTTY( ); - bool checkInput( lw::E_ConsoleKey& key , uint32_t& character ); - - bool getTerminalSize( ); - bool writeSequence( char const* sequence ); - bool writeSequence( char const* sequence , uint32_t size ); -}; - -/*----------------------------------------------------------------------------*/ - -T_ConsoleImpl_::T_ConsoleImpl_( ) -{ - // Buffer size: - // * "ESC[0m" always => 4 - // * 2 per enabled style => 6 - // * color: "38;2;" + 3 unsigned 8-bit numbers + 2 ";" separators => 16 - // That would be 26, but let's go for 32 instead - styleSeq_.ensureCapacity( 32 ); -} - -T_ConsoleImpl_::~T_ConsoleImpl_( ) -{ - shutdownConsole( ); -} - -bool T_ConsoleImpl_::initConsole( ) -{ - failed_ = false; - kbPos_ = 0; - ok_ = isatty( STDIN_FILENO ) && !IsBadTerminal_( ) && initTTY( ); - if ( ok_ && getTerminalSize( ) ) { - sizePolling_ = 0; - } - return ok_ && !failed_; -} - -void T_ConsoleImpl_::shutdownConsole( ) -{ - if ( ok_ ) { - setTextStyle( 0 , lw::E_TextColor::WHITE ); - tcsetattr( STDIN_FILENO , TCSAFLUSH , &initialTerm_ ); - } -} - -inline bool T_ConsoleImpl_::failed( ) const -{ - return failed_; -} - -bool T_ConsoleImpl_::resized( uint32_t& rows , uint32_t& cols ) const -{ - if ( cols_ != cols || rows_ != rows ) { - cols = cols_; - rows = rows_; - return true; - } - return false; -} - -bool T_ConsoleImpl_::getTerminalSize( uint32_t& rows , uint32_t& cols ) -{ - if ( !getTerminalSize( ) ) { - return false; - } - rows = rows_; - cols = cols_; - return true; -} - -/*----------------------------------------------------------------------------*/ - -bool T_ConsoleImpl_::readKey( lw::E_ConsoleKey& key , uint32_t& character ) -{ - if ( failed_ ) { - return false; - } - - do { - assert( kbPos_ < sizeof( keyBuf_ ) ); - const auto n( read( STDIN_FILENO , &keyBuf_[ kbPos_ ] , 1 ) ); - if ( n != 1 ) { - failed_ = failed_ || ( n == -1 ); - if ( n == 0 && kbPos_ == 0 ) { - sizePolling_ = ( sizePolling_ + 1 ) % 20; - if ( sizePolling_ == 0 ) { - getTerminalSize( ); - } - } - return false; - } - kbPos_ ++; - } while ( !checkInput( key , character ) ); - kbPos_ = 0; - return true; -} - -bool T_ConsoleImpl_::checkInput( lw::E_ConsoleKey& key , uint32_t& character ) -{ - assert( kbPos_ > 0 ); - - const uint8_t first( keyBuf_[ 0 ] ); - if ( kbPos_ == 1 ) { - // Escape or UTF-8 input - if ( first == 0x1b || first > 0x7f ) { - return false; - } - - switch ( first ) { - case 0x01: // Ctrl+A - key = lw::E_ConsoleKey::HOME; - return true; - - case 0x02: // Ctrl+B - key = lw::E_ConsoleKey::LEFT; - return true; - - case 0x03: // Ctrl+C - key = lw::E_ConsoleKey::INTERRUPT; - return true; - - case 0x04: // Ctrl+D - key = lw::E_ConsoleKey::EXIT; - return true; - - case 0x05: // Ctrl+E - key = lw::E_ConsoleKey::END; - return true; - - case 0x06: // Ctrl+F - key = lw::E_ConsoleKey::RIGHT; - return true; - - case 0x08: // Ctrl+H - case 0x7f: - key = lw::E_ConsoleKey::BACKSPACE; - return true; - - case 0x09: // Ctrl+I/Tab - key = lw::E_ConsoleKey::CHARACTER; - character = ' '; - return true; - - case 0x0b: // Ctrl+K - key = lw::E_ConsoleKey::KILL_REST; - return true; - - case 0x0c: // Ctrl+L - key = lw::E_ConsoleKey::CLEAR; - return true; - - case 0x0d: // Ctrl+M/Enter - key = lw::E_ConsoleKey::ENTER; - return true; - - case 0x0e: // Ctrl+N - key = lw::E_ConsoleKey::DOWN; - return true; - - case 0x10: // Ctrl+P - key = lw::E_ConsoleKey::UP; - return true; - - case 0x15: // Ctrl+U - key = lw::E_ConsoleKey::KILL_LINE; - return true; - - case 0x17: // Ctrl+W - key = lw::E_ConsoleKey::KILL_WORD; - return true; - - case 0x19: // Ctrl+Y - key = lw::E_ConsoleKey::PASTE; - return true; - } - - // Skip other control characters - if ( first < 32 ) { - kbPos_ = 0; - return false; - } - - key = lw::E_ConsoleKey::CHARACTER; - character = first; - return true; - } - - // Check for UTF-8 input - if ( first != 0x1b ) { - uint32_t l( 0 ); - if ( !lw::UTF8BufferInfo( (char const*) keyBuf_ , kbPos_ , l ) ) { - if ( kbPos_ > 4 ) { - kbPos_ = 0; - } - return false; - } - if ( l != 1 ) { - kbPos_ = 0; - return false; - } else { - key = lw::E_ConsoleKey::CHARACTER; - character = lw::UTF8GetCodepoint( (char const*) keyBuf_ ); - return true; - } - } - - // Escape sequences - const uint8_t second( keyBuf_[ 1 ] ); - if ( kbPos_ == 2 ) { - switch ( second ) { - case 0x7f: - key = lw::E_ConsoleKey::KILL_WORD; - return true; - - case 'f': - case 'F': - key = lw::E_ConsoleKey::WNEXT; - return true; - - case 'b': - case 'B': - key = lw::E_ConsoleKey::WPREV; - return true; - - default: - kbPos_ = 0; - case 'O': - case '[': - return false; - } - } - - // ESC-O-x sequences - if ( second == 'O' ) { - switch ( keyBuf_[ 2 ] ) { - case 'F': - key = lw::E_ConsoleKey::END; - return true; - case 'H': - key = lw::E_ConsoleKey::HOME; - return true; - case 'P': - key = lw::E_ConsoleKey::F1; - return true; - case 'Q': - key = lw::E_ConsoleKey::F2; - return true; - case 'R': - key = lw::E_ConsoleKey::F3; - return true; - case 'S': - key = lw::E_ConsoleKey::F4; - return true; - } - kbPos_ = 0; - return false; - } - - // Extended sequences - ESC-[, ends with ~ or uppercase letter - const uint8_t last( keyBuf_[ kbPos_ - 1 ] ); - if ( last != '~' && ( last < 'A' || last > 'Z' ) ) { - if ( kbPos_ == sizeof( keyBuf_ ) - 1 ) { - kbPos_ = 0; - } - return false; - } - - // Check the list - uint32_t idx( 0 ); - keyBuf_[ kbPos_ ] = 0; - while ( InputSequences_[ idx ] != nullptr ) { - if ( !strcmp( (char const*) keyBuf_ + 2 , InputSequences_[ idx ] ) ) { - key = InputKeys_[ idx ]; - return true; - } - idx ++; - } - kbPos_ = 0; - return false; -} - -/*----------------------------------------------------------------------------*/ - -bool T_ConsoleImpl_::clearScreen( ) -{ - return writeSequence( CCClearScreen_ , sizeof( CCClearScreen_ ) - 1 ); -} - -void T_ConsoleImpl_::setTextStyle( uint8_t style , lw::T_TextColor color ) -{ - styleSeq_.clear( ); - styleSeq_ << "\033[0"; - if ( ( style & uint8_t( lw::E_TextStyle::BOLD ) ) != 0 ) { - styleSeq_ << ";1"; - } - if ( ( style & uint8_t( lw::E_TextStyle::ITALIC ) ) != 0 ) { - styleSeq_ << ";3"; - } - if ( ( style & uint8_t( lw::E_TextStyle::UNDERLINE ) ) != 0 ) { - styleSeq_ << ";4"; - } - if ( color.type == lw::E_TextColor::CUSTOM ) { - styleSeq_ << ";38;2;" << color.r - << ';' << color.g - << ';' << color.b; - } else { - styleSeq_ << ';' << ( 30 + uint8_t( color.type ) ); - } - styleSeq_ << 'm'; - writeSequence( styleSeq_.data( ) , styleSeq_.size( ) ); -} - -void T_ConsoleImpl_::printCharacter( lw::T_Character c ) -{ - char buf[ 8 ]; - uint32_t l( UTF8PutCodepoint( buf , 7 , c ) ); - if ( l == 0 ) { - return; - } - writeSequence( buf , l ); -} - -void T_ConsoleImpl_::nextLine( ) -{ - writeSequence( CCNextLine_ , sizeof( CCNextLine_ ) - 1 ); -} - -void T_ConsoleImpl_::clearLine( ) -{ - writeSequence( CCClearLine_ , sizeof( CCClearLine_ ) - 1 ); -} - -void T_ConsoleImpl_::clearLines( uint32_t count ) -{ - assert( count > 0 ); - while ( --count ) { - writeSequence( CCClearLineUp_ , sizeof( CCClearLineUp_ ) - 1 ); - } - clearLine( ); -} - -void T_ConsoleImpl_::moveCursor( int32_t x , int32_t y ) -{ - styleSeq_.clear( ); - if ( x ) { - styleSeq_ << "\033[" - << ( x > 0 ? x : -x ) - << ( x > 0 ? 'C' : 'D' ); - } - if ( y ) { - styleSeq_ << "\033[" - << ( y > 0 ? y : -y ) - << ( y > 0 ? 'B' : 'A' ); - } - if ( styleSeq_.size( ) ) { - writeSequence( styleSeq_.data( ) , styleSeq_.size( ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -bool T_ConsoleImpl_::initTTY( ) -{ - if ( tcgetattr( STDIN_FILENO , &initialTerm_ ) == -1 ) { - failed_ = true; - return false; - } - - termios rawTerm( initialTerm_ ); - rawTerm.c_iflag &= ~( BRKINT | ICRNL | INPCK | ISTRIP | IXON ); - rawTerm.c_oflag &= ~OPOST; - rawTerm.c_cflag |= CS8; - rawTerm.c_lflag &= ~( ECHO | ICANON | IEXTEN | ISIG ); - rawTerm.c_cc[ VMIN ] = 0; - rawTerm.c_cc[ VTIME ] = 0; - - if ( tcsetattr( STDIN_FILENO , TCSAFLUSH , &rawTerm ) >= 0 ) { - return getTerminalSize( ); - } else { - failed_ = true; - return false; - } -} - -/*----------------------------------------------------------------------------*/ - -bool T_ConsoleImpl_::getTerminalSize( ) -{ - // Try obtaining the size using ioctl - winsize ws; - if ( ioctl( STDIN_FILENO , TIOCGWINSZ , &ws ) != -1 && ws.ws_col != 0 ) { - rows_ = ws.ws_row; - cols_ = ws.ws_col; - return true; - } - - // Otherwise, we need to move the cursor to the bottom/right corner, then - // get its position. - return writeSequence( CCGetTermSizeStart_ , sizeof( CCGetTermSizeStart_ ) - 1 ) - && getCursorPosition( cols_ , rows_ ) - && writeSequence( CCGetTermSizeEnd_ , sizeof( CCGetTermSizeEnd_ ) - 1 ); -} - -bool T_ConsoleImpl_::getCursorPosition( uint32_t& column , uint32_t& row ) -{ - if ( failed_ || tcflush( STDIN_FILENO , TCIFLUSH ) != 0 ) { - failed_ = true; - return false; - } - if ( !writeSequence( CCGetCursorPos_ , sizeof( CCGetCursorPos_ ) - 1 ) ) { - return false; - } - - char buf[ 32 ]; - size_t i( 0 ); - while ( i < sizeof( buf ) ) { - if ( read( STDIN_FILENO , buf + i , 1 ) != 1 ) { - i = sizeof( buf ); - break; - } - if ( buf[ i ] == 'R' ) { - break; - } - i ++; - } - - if ( i == sizeof( buf ) || i < 6 || buf[ 0 ] != 27 || buf[ 1 ] != '[' ) { - failed_ = true; - return false; - } - - buf[ i ] = 0; - if ( sscanf( buf + 2 , "%d;%d" , &row , &column ) != 2 ) { - failed_ = true; - return false; - } - return true; -} - -#if 0 -bool T_ConsoleImpl_::writeSequence( char const* sequence ) -{ - if ( failed_ ) { - return false; - } - - const int n( strlen( sequence ) ); - if ( write( STDOUT_FILENO , sequence , n ) != n ) { - failed_ = true; - return false; - } - - return true; -} -#endif - -bool T_ConsoleImpl_::writeSequence( char const* sequence , uint32_t size ) -{ - if ( failed_ ) { - return false; - } - - if ( write( STDOUT_FILENO , sequence , size ) != size ) { - failed_ = true; - return false; - } - - return true; -} - - -} diff --git a/src/Console.cc b/src/Console.cc deleted file mode 100644 index 2c217b5..0000000 --- a/src/Console.cc +++ /dev/null @@ -1,1346 +0,0 @@ -/******************************************************************************/ -/* CONSOLE SUPPORT ************************************************************/ -/******************************************************************************/ - -#include -#include -using namespace lw; - - -/*= T_TextBuilder ============================================================*/ - -T_TextBuilder::T_TextBuilder( ) noexcept - : sb_( ) , chunks_( 16 ) , flushedLength_( 0 ) , - cStyle_( 0 ) , cColor_( E_TextColor::WHITE ) -{ } - -/*----------------------------------------------------------------------------*/ - -T_TextBuilder::T_TextBuilder( T_TextBuilder&& other ) noexcept - : T_TextBuilder( ) -{ - swap( *this , other ); -} - -T_TextBuilder& T_TextBuilder::operator =( T_TextBuilder&& other ) noexcept -{ - sb_ = std::move( other.sb_ ); - chunks_ = std::move( other.chunks_ ); - flushedLength_ = other.flushedLength_; - cStyle_ = other.cStyle_; - cColor_ = other.cColor_; - other.flushedLength_ = other.cStyle_ = 0; - other.cColor_ = E_TextColor::WHITE; - return *this; -} - -/*----------------------------------------------------------------------------*/ - -M_DEFINE_SWAP( T_TextBuilder ) -{ - using std::swap; - swap( lhs.sb_ , rhs.sb_ ); - swap( lhs.chunks_ , rhs.chunks_ ); - swap( lhs.flushedLength_ , rhs.flushedLength_ ); - swap( lhs.cStyle_ , rhs.cStyle_ ); - swap( lhs.cColor_ , rhs.cColor_ ); -} - -/*----------------------------------------------------------------------------*/ - -void T_TextBuilder::clear( ) -{ - chunks_.clear( ); - sb_.clear( ); - flushedLength_ = 0; - cStyle_ = 0; - cColor_ = E_TextColor::WHITE; -} - -void T_TextBuilder::reset( bool style , bool color ) -{ - if ( style ) { - setStyle( 0 ); - } - if ( color ) { - setColor( E_TextColor::WHITE ); - } -} - -/*----------------------------------------------------------------------------*/ - -void T_TextBuilder::setStyle( uint8_t style ) -{ - if ( style == cStyle_ ) { - return; - } - flush( ); - cStyle_ = style; -} - -void T_TextBuilder::setColor( T_TextColor color ) -{ - if ( color == cColor_ ) { - return; - } - flush( ); - cColor_ = color; -} - -/*----------------------------------------------------------------------------*/ - -T_TextBuilder& T_TextBuilder::append( - T_Text const& text ) noexcept -{ - flush( ); - const uint32_t nChunks( text.chunks( ) ); - for ( uint32_t i = 0 ; i < nChunks ; i ++ ) { - chunks_.add( text.chunk( i ) ); - } - sb_ << text.string( ); - flushedLength_ = sb_.size( ); - return *this; -} - -T_TextBuilder& T_TextBuilder::append( - T_TextBuilder const& text ) noexcept -{ - flush( ); - chunks_.addAll( text.chunks_ ); - sb_ << text.sb_; - flushedLength_ += text.flushedLength_; - return *this; -} - -/*----------------------------------------------------------------------------*/ - -void T_TextBuilder::flush( ) -{ - const auto len( sb_.length( ) ); - if ( flushedLength_ == len ) { - return; - } - - T_TextChunk& chunk( chunks_.addNew( ) ); - chunk.length = len - flushedLength_; - chunk.style = cStyle_; - chunk.color = cColor_; - flushedLength_ = len; -} - - -/*= T_Text ===================================================================*/ - -T_Text::T_Text( ) - : string_( ) , chunks_( 1 ) -{ } - -T_Text::T_Text( T_TextBuilder const& builder ) - : string_( builder.sb_ ) , chunks_( std::max( 1u , builder.chunksCount( ) ) ) -{ - initChunks( builder ); -} - -T_Text::T_Text( T_TextBuilder&& builder ) - : string_( std::move( builder.sb_ ) ) , - chunks_( std::max( 1u , builder.chunksCount( ) ) ) -{ - initChunks( builder ); - builder.clear( ); -} - -/*----------------------------------------------------------------------------*/ - -M_DEFINE_SWAP( T_Text ) -{ - using std::swap; - swap( lhs.string_ , rhs.string_ ); - swap( lhs.chunks_ , rhs.chunks_ ); -} - -/*----------------------------------------------------------------------------*/ - -T_TextChunk const& T_Text::chunkAt( uint32_t pos ) const -{ - uint32_t sz( 0 ); - int idx( -1 ); - while ( pos >= sz ) { - idx ++; - sz += chunks_[ idx ].length; - } - return chunks_[ idx ]; -} - -/*----------------------------------------------------------------------------*/ - -void T_Text::initChunks( T_TextBuilder const& builder ) -{ - chunks_.addAll( builder.chunks_ ); - if ( chunks_.size( ) < chunks_.growth( ) ) { - const auto len( string_.length( ) ); - T_TextChunk& chunk( chunks_.addNew( ) ); - chunk.length = len - builder.flushedLength_; - chunk.style = builder.cStyle_; - chunk.color = builder.cColor_; - } -} - - -/*= T_ConsoleLineState =======================================================*/ - -T_ConsoleLineState::T_ConsoleLineState( ) - : characters_( GROWTH ) -{ - reset( ); -} - -void T_ConsoleLineState::reset( ) -{ - size_ = 0; - pos_ = 0; - historyIndex_ = 0; -} - -void T_ConsoleLineState::setContents( T_String const& contents , uint32_t index ) -{ - const uint32_t len( contents.length( ) ); - ensureCapacity( len ); - - T_StringIterator it( contents ); - while ( !it.atEnd( ) ) { - characters_[ it.index( ) ] = T_Character( it ); - it.next( ); - } - - historyIndex_ = index; - size_ = pos_ = len; -} - -/*----------------------------------------------------------------------------*/ - -T_String T_ConsoleLineState::getContents( ) const -{ - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < size_ ; i ++ ) { - sb << T_Character( characters_[ i ] ); - } - return T_String( std::move( sb ) ); -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsoleLineState::prevWord( ) -{ - while ( pos_ > 0 && characters_[ pos_ - 1 ] == ' ' ) { - pos_ --; - } - while ( pos_ > 0 && characters_[ pos_ - 1 ] != ' ' ) { - pos_ --; - } -} - -void T_ConsoleLineState::nextWord( ) -{ - while ( pos_ < size_ && characters_[ pos_ ] == ' ' ) { - pos_ ++; - } - while ( pos_ < size_ && characters_[ pos_ ] != ' ' ) { - pos_ ++; - } -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsoleLineState::removeCharacter( ) -{ - if ( pos_ == size_ ) { - return; - } - size_--; - if ( pos_ < size_ ) { - memmove( &characters_[ pos_ ] , &characters_[ pos_ + 1 ] , - ( size_ - pos_ ) * sizeof( uint32_t ) ); - } -} - -void T_ConsoleLineState::removeWord( T_Buffer< uint32_t >& cpBuf , uint32_t& cpLength ) -{ - const uint32_t end( pos_ ); - prevWord( ); - if ( pos_ == end ) { - return; - } - - const uint32_t rmCount( end - pos_ ); - cpLength = rmCount; - if ( cpBuf.size( ) < rmCount ) { - cpBuf.resize( rmCount ); - } - memcpy( &cpBuf[ 0 ] , &characters_[ pos_ ] , rmCount * sizeof( uint32_t ) ); - - size_ -= rmCount; - if ( pos_ < size_ ) { - memmove( &characters_[ pos_ ] , &characters_[ end ] , - ( size_ - pos_ ) * sizeof( uint32_t ) ); - } -} - -void T_ConsoleLineState::removeRestOfLine( T_Buffer< uint32_t >& cpBuf , uint32_t& cpLength ) -{ - if ( pos_ == size_ ) { - return; - } - - const uint32_t rmCount( size_ - pos_ ); - cpLength = rmCount; - if ( cpBuf.size( ) < rmCount ) { - cpBuf.resize( rmCount ); - } - memcpy( &cpBuf[ 0 ] , &characters_[ pos_ ] , rmCount * sizeof( uint32_t ) ); - - size_ = pos_; -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsoleLineState::insert( T_Character c ) -{ - ensureCapacity( size_ + 1 ); - if ( pos_ < size_ ) { - memmove( &characters_[ pos_ + 1 ] , &characters_[ pos_ ] , - ( size_ - pos_ ) * sizeof( uint32_t ) ); - } - size_ ++; - characters_[ pos_ ++ ] = c; -} - -void T_ConsoleLineState::insert( T_String const& s ) -{ - const uint32_t length( s.length( ) ); - - ensureCapacity( size_ + length ); - if ( pos_ < size_ ) { - memmove( &characters_[ pos_ + length ] , &characters_[ pos_ ] , - ( size_ - pos_ ) * sizeof( uint32_t ) ); - } - - T_StringIterator it( s ); - while ( !it.atEnd( ) ) { - const T_Character c( it ); - const uint32_t value( c.isControl( ) ? 32 : uint32_t( c ) ); - characters_[ pos_ + it.index( ) ] = value; - it.next( ); - } - - size_ += length; - pos_ += length; -} - -void T_ConsoleLineState::insert( T_Buffer< uint32_t > const& buffer , uint32_t length ) -{ - if ( length == 0 ) { - return; - } - - ensureCapacity( size_ + length ); - if ( pos_ < size_ ) { - memmove( &characters_[ pos_ + length ] , &characters_[ pos_ ] , - ( size_ - pos_ ) * sizeof( uint32_t ) ); - } - size_ += length; - memcpy( &characters_[ pos_ ] , &buffer[ 0 ] , length * sizeof( uint32_t ) ); - pos_ += length; -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsoleLineState::ensureCapacity( uint32_t needed ) -{ - const uint32_t extra( needed + GROWTH - 1 ); - const uint32_t actual( extra - extra % GROWTH ); - if ( actual > characters_.size( ) ) { - characters_.resize( actual ); - } -} - - -/*= T_ConsoleControl_ =========================================================*/ - -// Information sent to the console -namespace { -struct T_ConsoleControl_ -{ - enum { - C_TERMINATE , // End thread - C_SETMODE , // Set interaction mode - C_SETPROMPT , // Set prompt text - C_SETEXIT , // Set text for Ctrl+D - C_SETPROGRESS , // Set progress information - C_SETSHORTCUT , // Set a keyboard shortcut - C_SETHISTSIZE , // Set maximal history size - C_SETHISTORY , // Replace history contents - C_PRINT , // Print text - } type; - T_Variant data; -}; -} // namespace - - -/*= T_ConsolePrivate_ ========================================================*/ - -// Load the implementation -#ifdef _WIN32 -# error "Not implemented!" -#else -# include "Console-Unix.hh" -#endif - -namespace { -struct T_ConsolePrivate_ -{ - enum { - C_TERMINATED , // Thread stopped - C_OUTPUT , // Output mode - C_INPUT , // Input mode - C_INPUT_READY , // Input finished - C_PROGRESS , // Progress display - C_INTERRUPTED // Progress display, interrupted - } state_; - - T_Text progress_; - - T_Text prompt_; - T_String exitLine_; - T_String line_; - - T_ConsoleLineState input_; - uint32_t ilLines_ , ilLastPromptLine_; - uint32_t ilCursorX_ , ilCursorY_; - - T_Buffer< uint32_t > cpBuffer_; - uint32_t cpLength_; - - T_String shortcuts_[ T_Console::NbShortcuts ]; - - T_Array< T_String > history_; - uint32_t maxHistory_; - uint32_t historyPos_; - - OP_Thread thread_; - - T_Mutex controlMutex_; - T_Condition controlCond_; - T_RingBuffer< T_ConsoleControl_ > control_; - - T_ConsoleImpl_ impl_; - uint32_t width_ , height_; - - // -------------------------------------------------------------------- - - T_ConsolePrivate_( ); - ~T_ConsolePrivate_( ); - - E_ConsoleInteractionMode interactionMode( ) const; - - // -------------------------------------------------------------------- - - bool start( ); - void terminate( ); - void resetData( ); - - void mainLoop( ); - bool handleControlMessage( T_ConsoleControl_& o ); - - // -------------------------------------------------------------------- - - void printText( T_Text const& text , bool line ); - void printProgress( ); - - // -------------------------------------------------------------------- - - void inputKey( E_ConsoleKey key , T_Character character ); - void clearInputLine( ); - void printInputLine( ); - void moveInputCursor( ); - - // -------------------------------------------------------------------- - - void setHistorySize( uint32_t newMax ); - void setHistory( T_Array< T_String >& newData ); - - void getTextSize( T_String const& text , uint32_t& lines , uint32_t& lastLineLength ); - - void updateHistory( T_String const& string ); - void newHistoryEntry( ); - - // -------------------------------------------------------------------- - - void sendToThread( T_ConsoleControl_&& o ); - bool receiveFromMain( T_ConsoleControl_& output ); -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -inline T_ConsolePrivate_::T_ConsolePrivate_( ) - : maxHistory_( T_Console::DefaultHistory ) , - historyPos_( 0 ) -{ - history_.addNew( ); -} - -inline T_ConsolePrivate_::~T_ConsolePrivate_( ) -{ - terminate( ); -} - -inline E_ConsoleInteractionMode T_ConsolePrivate_::interactionMode( ) const -{ - switch ( state_ ) { - case C_INPUT: - case C_INPUT_READY: - return E_ConsoleInteractionMode::INPUT; - case C_PROGRESS: - case C_INTERRUPTED: - return E_ConsoleInteractionMode::PROGRESS; - default: - return E_ConsoleInteractionMode::OUTPUT; - } -} - -/*----------------------------------------------------------------------------*/ - -bool T_ConsolePrivate_::start( ) -{ - if ( impl_.initConsole( ) ) { - resetData( ); - state_ = C_OUTPUT; - thread_ = NewOwned< T_Thread >( [this]() { mainLoop( ); } ); - return true; - } else { - return false; - } -} - -void T_ConsolePrivate_::terminate( ) -{ - if ( thread_ ) { - T_ConsoleControl_ out; - out.type = T_ConsoleControl_::C_TERMINATE; - sendToThread( std::move( out ) ); - thread_->join( ); - thread_.clear( ); - resetData( ); - } -} - -void T_ConsolePrivate_::resetData( ) -{ - control_.free( ); - line_ = T_String( ); - prompt_ = T_Text( ); - exitLine_ = T_String( ); - progress_ = T_Text( ); - input_.reset( ); -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsolePrivate_::mainLoop( ) -{ - E_ConsoleKey key( E_ConsoleKey::CHARACTER ); - uint32_t character( 0 ); - T_ConsoleControl_ o; - bool keepRunning( true ); - - impl_.getTerminalSize( height_ , width_ ); - while ( keepRunning && !impl_.failed( ) ) { - if ( impl_.readKey( key , character ) ) { - if ( key == E_ConsoleKey::CLEAR ) { - impl_.clearScreen( ); - if ( interactionMode( ) == E_ConsoleInteractionMode::PROGRESS ) { - printProgress( ); - } else if ( state_ == C_INPUT ) { - printInputLine( ); - } - - } else if ( state_ == C_PROGRESS && key == E_ConsoleKey::INTERRUPT ) { - state_ = C_INTERRUPTED; - - } else if ( state_ == C_INPUT ) { - inputKey( key , character ); - } - - } else if ( receiveFromMain( o ) ) { - keepRunning = handleControlMessage( o ); - } else if ( impl_.resized( height_ , width_ ) ) { - if ( state_ == C_PROGRESS || state_ == C_INTERRUPTED ) { - printProgress( ); - } - } - } - - impl_.shutdownConsole( ); -} - -bool T_ConsolePrivate_::handleControlMessage( T_ConsoleControl_& o ) -{ - switch ( o.type ) { - - case T_ConsoleControl_::C_TERMINATE: - if ( state_ == C_INPUT ) { - clearInputLine( ); - } else if ( state_ == C_PROGRESS || state_ == C_INTERRUPTED ) { - impl_.clearLine( ); - } - state_ = C_TERMINATED; - return false; - - case T_ConsoleControl_::C_SETMODE: - { - const auto m( o.data.value< E_ConsoleInteractionMode >( ) ); - if ( m == E_ConsoleInteractionMode::OUTPUT ) { - if ( state_ == C_PROGRESS || state_ == C_INTERRUPTED ) { - impl_.clearLine( ); - } else if ( state_ == C_INPUT ) { - clearInputLine( ); - } - state_ = C_OUTPUT; - } else if ( m == E_ConsoleInteractionMode::INPUT ) { - if ( state_ != C_INPUT_READY ) { - if ( state_ == C_PROGRESS || state_ == C_INTERRUPTED ) { - impl_.clearLine( ); - } - input_.reset( ); - printInputLine( ); - state_ = C_INPUT; - } - } else { - assert( m == E_ConsoleInteractionMode::PROGRESS ); - if ( state_ == C_INPUT ) { - clearInputLine( ); - } - state_ = C_PROGRESS; - printProgress( ); - } - } - break; - - case T_ConsoleControl_::C_SETPROMPT: - if ( state_ == C_INPUT ) { - clearInputLine( ); - } - prompt_ = o.data.value< T_Text >( ); - if ( state_ == C_INPUT ) { - printInputLine( ); - } - break; - - case T_ConsoleControl_::C_SETEXIT: - exitLine_ = o.data.value< T_String >( ); - break; - - case T_ConsoleControl_::C_SETPROGRESS: - progress_ = o.data.value< T_Text >( ); - if ( interactionMode( ) == E_ConsoleInteractionMode::PROGRESS ) { - printProgress( ); - } - break; - - case T_ConsoleControl_::C_SETSHORTCUT: - { - auto const& p( o.data.value< std::pair< int , T_String > >( ) ); - shortcuts_[ p.first ] = p.second; - } - break; - - case T_ConsoleControl_::C_SETHISTSIZE: - setHistorySize( o.data.value< uint32_t >( ) ); - break; - - case T_ConsoleControl_::C_SETHISTORY: - setHistory( o.data.value< T_Array< T_String > >( ) ); - break; - - case T_ConsoleControl_::C_PRINT: - if ( state_ == C_PROGRESS || state_ == C_INTERRUPTED ) { - impl_.clearLine( ); - } else if ( state_ == C_INPUT ) { - clearInputLine( ); - } - printText( o.data.value< T_Text >( ) , true ); - if ( state_ == C_PROGRESS || state_ == C_INTERRUPTED ) { - printProgress( ); - } else if ( state_ == C_INPUT ) { - printInputLine( ); - } - break; - } - - return true; -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsolePrivate_::printText( T_Text const& text , bool line ) -{ - T_StringIterator it( text.string( ) ); - uint32_t chunkLeft( 0 ); - uint32_t chunkIndex( 0 ); - bool lastWasNL( false ); - uint32_t cols( 0 ); - while ( !( it.atEnd( ) || impl_.failed( ) ) ) { - if ( chunkLeft == 0 ) { - T_TextChunk const& chunk( text.chunk( chunkIndex ++ ) ); - chunkLeft = chunk.length; - impl_.setTextStyle( chunk.style , chunk.color ); - } - - T_Character c( it ); - lastWasNL = ( c == '\n' ); - if ( !c.isControl( ) ) { - impl_.printCharacter( c ); - cols ++; - } else if ( c == '\t' ) { - do { - impl_.printCharacter( ' ' ); - cols ++; - } while ( cols % 8 != 0 ); - } else if ( c == '\n' ) { - impl_.nextLine( ); - cols = 0; - } - it.next( ); - chunkLeft --; - } - if ( !lastWasNL && line ) { - impl_.nextLine( ); - } -} - -void T_ConsolePrivate_::printProgress( ) -{ - impl_.getTerminalSize( height_ , width_ ); - impl_.clearLine( ); - - T_StringIterator it( progress_.string( ) ); - uint32_t chunkLeft( 0 ); - uint32_t chunkIndex( 0 ); - uint32_t cols( 0 ); - while ( !( it.atEnd( ) || impl_.failed( ) || cols == width_ ) ) { - if ( chunkLeft == 0 ) { - T_TextChunk const& chunk( progress_.chunk( chunkIndex ++ ) ); - chunkLeft = chunk.length; - impl_.setTextStyle( chunk.style , chunk.color ); - } - - T_Character c( it ); - if ( !c.isControl( ) ) { - impl_.printCharacter( c ); - cols ++; - } else if ( c == '\t' ) { - do { - impl_.printCharacter( ' ' ); - cols ++; - } while ( cols % 8 != 0 && cols < width_ ); - } else if ( c == '\n' ) { - break; - } - it.next( ); - chunkLeft --; - } -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsolePrivate_::inputKey( E_ConsoleKey key , T_Character character ) -{ - bool cursorMoved( true ) , stringChanged( false ); - switch ( key ) { - - case E_ConsoleKey::CLEAR: - // This should never happen, but better safe than sorry - return; - - case E_ConsoleKey::ENTER: - input_.toEnd( ); - moveInputCursor( ); - line_ = input_.getContents( ); - { - const uint32_t hs( history_.size( ) ); - if ( line_ && ( hs == 1 || history_[ ( historyPos_ - 1 + hs ) % hs ] != line_ ) ) { - history_[ historyPos_ ] = line_; - newHistoryEntry( ); - } else { - history_[ historyPos_ ] = T_String( ); - } - } - input_.reset( ); - impl_.nextLine( ); - state_ = C_INPUT_READY; - return; - - case E_ConsoleKey::INTERRUPT: - if ( input_.size( ) != 0 ) { - input_.reset( ); - impl_.nextLine( ); - printInputLine( ); - } - return; - - case E_ConsoleKey::CHARACTER: - input_.insert( character ); - stringChanged = true; - break; - - case E_ConsoleKey::UP: - { - const auto hs( history_.size( ) ) , hi( input_.historyIndex( ) ); - if ( hi == hs - 1 ) { - cursorMoved = false; - } else { - if ( input_.size( ) ) { - updateHistory( input_.getContents( ) ); - } - input_.setContents( history_[ ( historyPos_ - hi - 1 + hs ) % hs ] , hi + 1 ); - stringChanged = true; - } - } - break; - - case E_ConsoleKey::DOWN: - { - const auto hs( history_.size( ) ) , hi( input_.historyIndex( ) ); - if ( hi == 0 ) { - cursorMoved = false; - } else { - if ( input_.size( ) ) { - updateHistory( input_.getContents( ) ); - } - input_.setContents( history_[ ( historyPos_ - hi + 1 + hs ) % hs ] , hi - 1 ); - stringChanged = true; - } - } - break; - - case E_ConsoleKey::LEFT: - if ( input_.pos( ) == 0 ) { - cursorMoved = false; - } else { - input_.left( ); - } - break; - - case E_ConsoleKey::RIGHT: - if ( input_.pos( ) == input_.size( ) ) { - cursorMoved = false; - } else { - input_.right( ); - } - break; - - case E_ConsoleKey::WPREV: - if ( input_.pos( ) == 0 ) { - cursorMoved = false; - } else { - input_.prevWord( ); - } - break; - - case E_ConsoleKey::WNEXT: - if ( input_.pos( ) == input_.size( ) ) { - cursorMoved = false; - } else { - input_.nextWord( ); - } - break; - - case E_ConsoleKey::HOME: - if ( input_.pos( ) == 0 ) { - cursorMoved = false; - } else { - input_.toStart( ); - } - break; - - case E_ConsoleKey::END: - if ( input_.pos( ) == input_.size( ) ) { - cursorMoved = false; - } else { - input_.toEnd( ); - } - break; - - case E_ConsoleKey::EXIT: - if ( input_.size( ) == 0 && exitLine_ ) { - input_.setContents( exitLine_ , 0 ); - clearInputLine( ); - printInputLine( ); - impl_.nextLine( ); - line_ = exitLine_; - state_ = C_INPUT_READY; - return; - } - case E_ConsoleKey::DELETE: - if ( input_.pos( ) == input_.size( ) ) { - cursorMoved = false; - } else { - input_.removeCharacter( ); - stringChanged = true; - } - break; - - case E_ConsoleKey::BACKSPACE: - if ( input_.pos( ) == 0 ) { - cursorMoved = false; - } else { - input_.left( ); - input_.removeCharacter( ); - stringChanged = true; - } - break; - - case E_ConsoleKey::KILL_WORD: - if ( input_.pos( ) == 0 ) { - cursorMoved = false; - } else { - input_.removeWord( cpBuffer_ , cpLength_ ); - stringChanged = true; - } - break; - - case E_ConsoleKey::KILL_REST: - if ( input_.pos( ) == input_.size( ) ) { - cursorMoved = false; - } else { - input_.removeRestOfLine( cpBuffer_ , cpLength_ ); - stringChanged = true; - } - break; - - case E_ConsoleKey::KILL_LINE: - if ( 0 == input_.size( ) ) { - cursorMoved = false; - } else { - input_.toStart( ); - input_.removeRestOfLine( cpBuffer_ , cpLength_ ); - stringChanged = true; - } - break; - - case E_ConsoleKey::PASTE: - if ( 0 == cpLength_ ) { - cursorMoved = false; - } else { - input_.insert( cpBuffer_ , cpLength_ ); - stringChanged = true; - } - break; - - default: - { - assert( key >= E_ConsoleKey::F1 ); - const T_String shortcut( shortcuts_[ int( key ) - int( E_ConsoleKey::F1 ) ] ); - if ( shortcut ) { - input_.insert( shortcut ); - stringChanged = true; - } else { - cursorMoved = false; - } - } - break; - } - - if ( stringChanged ) { - clearInputLine( ); - printInputLine( ); - } else if ( cursorMoved ) { - moveInputCursor( ); - } -} - -void T_ConsolePrivate_::clearInputLine( ) -{ - if ( ilLines_ != 0 ) { - impl_.moveCursor( 0 , ilLines_ - ilCursorY_ - 1 ); - impl_.clearLines( ilLines_ ); - ilLines_ = 0; - } -} - -void T_ConsolePrivate_::printInputLine( ) -{ - uint32_t promptLines; - getTextSize( prompt_.string( ) , promptLines , ilLastPromptLine_ ); - - const uint32_t iSize( input_.size( ) ); - const uint32_t inputFull( ilLastPromptLine_ + iSize + 1 ); - const uint32_t inputLines( inputFull / width_ - + ( inputFull % width_ != 0 ? 1 : 0 ) ); - const uint32_t totalLines( inputLines + promptLines - 1 ); - ilLines_ = totalLines; - - if ( prompt_.string( ) ) { - printText( prompt_ , false ); - } else { - impl_.setTextStyle( 0 , E_TextColor::WHITE ); - } - for ( uint32_t i = 0 ; i < iSize ; i ++ ) { - impl_.printCharacter( input_[ i ] ); - } - impl_.printCharacter( ' ' ); - - ilCursorY_ = totalLines - 1; - ilCursorX_ = inputFull % width_; - if ( ilCursorX_ == 0 ) { - ilCursorX_ = width_ - 1; - } - moveInputCursor( ); -} - -void T_ConsolePrivate_::moveInputCursor( ) -{ - if ( ilLines_ == 0 ) { - return; - } - const uint32_t iPos( input_.pos( ) ); - const int32_t line( ( iPos + ilLastPromptLine_ ) / width_ ); - const int32_t column( ( iPos + ilLastPromptLine_ ) % width_ ); - impl_.moveCursor( column - ilCursorX_ , line - ilCursorY_ ); - ilCursorX_ = column; - ilCursorY_ = line; -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsolePrivate_::setHistorySize( uint32_t newMax ) -{ - assert( state_ != C_INPUT ); - assert( newMax > 0 ); - - if ( newMax == maxHistory_ ) { - return; - } - maxHistory_ = newMax; - - const uint32_t hs( history_.size( ) ); - if ( hs > maxHistory_ || historyPos_ != hs - 1 ) { - const uint32_t cs( std::min( hs , maxHistory_ ) ); - const uint32_t start( historyPos_ + hs - cs + 1 ); - T_Array< T_String > nh; - for ( uint32_t i = 0 ; i < cs ; i ++ ) { - nh.add( std::move( history_[ ( start + i ) % hs ] ) ); - } - swap( history_ , nh ); - historyPos_ = cs - 1; - } -} - -void T_ConsolePrivate_::setHistory( T_Array< T_String >& newData ) -{ - assert( state_ != C_INPUT ); - const auto sz( newData.size( ) ); - if ( sz > maxHistory_ ) { - history_ = newData.moveRange( sz - maxHistory_ , sz - 1 ); - } else { - swap( history_ , newData ); - if ( sz == 0 ) { - history_.addNew( ); - historyPos_ = 0; - } else { - historyPos_ = sz - 1; - } - } - if ( history_[ historyPos_ ] ) { - newHistoryEntry( ); - } -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsolePrivate_::getTextSize( T_String const& text , uint32_t& lines , uint32_t& lastLineLength ) -{ - T_StringIterator it( text ); - lines = 1; - lastLineLength = 0; - while ( !it.atEnd( ) ) { - T_Character c( it ); - it.next( ); - - if ( c == '\n' ) { - lines ++; - lastLineLength = 0; - } else if ( c == '\t' ) { - lastLineLength += 8 - ( lastLineLength % 8 ); - } else if ( !c.isControl( ) ) { - lastLineLength ++; - } - - while ( lastLineLength >= width_ ) { - lines ++; - lastLineLength -= width_; - } - } -} - -/*----------------------------------------------------------------------------*/ - -inline void T_ConsolePrivate_::updateHistory( T_String const& string ) -{ - const uint32_t hs( history_.size( ) ); - assert( hs > 0 ); - history_[ ( historyPos_ - input_.historyIndex( ) + hs ) % hs ] = string; -} - -void T_ConsolePrivate_::newHistoryEntry( ) -{ - if ( history_.size( ) < maxHistory_ ) { - assert( historyPos_ == history_.size( ) - 1 ); - historyPos_ ++; - history_.addNew( ); - } else { - historyPos_ = ( historyPos_ + 1 ) % maxHistory_; - history_[ historyPos_ ] = T_String( ); - } -} - -/*----------------------------------------------------------------------------*/ - -void T_ConsolePrivate_::sendToThread( T_ConsoleControl_&& o ) -{ - assert( thread_ ); - T_ScopeLock lock( controlMutex_ ); - control_.put( std::move( o ) ); - controlCond_.notify_one( ); -} - -bool T_ConsolePrivate_::receiveFromMain( T_ConsoleControl_& output ) -{ - using namespace std::chrono_literals; - T_ExclusiveLock lock( controlMutex_ ); - controlCond_.wait_for( lock , 20ms , [this]() { - return control_.size( ) != 0; - } ); - return control_.readNext( output ); -} - - -/*= T_Console ================================================================*/ - -T_Console::T_Console( ) - : A_PrivateImplementation( new T_ConsolePrivate_( ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -bool T_Console::mode( E_ConsoleMode mode ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( mode == E_ConsoleMode::DISABLED ) { - pi.terminate( ); - return true; - } - return isActive( ) || pi.start( ) || mode == E_ConsoleMode::OPTIONAL; -} - -bool T_Console::isActive( ) const -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - return pi.thread_ && pi.state_ != pi.C_TERMINATED; -} - -/*----------------------------------------------------------------------------*/ - -void T_Console::interactionMode( E_ConsoleInteractionMode mode ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.thread_ ) { - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_SETMODE; - o.data = mode; - pi.sendToThread( std::move( o ) ); - } -} - -E_ConsoleInteractionMode T_Console::interactionMode( ) const -{ - return p< T_ConsolePrivate_ >( ).interactionMode( ); -} - -void T_Console::wait( ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - bool hasMessages( true ); - while ( isActive( ) && hasMessages ) { - { - T_ScopeLock lock( pi.controlMutex_ ); - hasMessages = pi.control_.size( ) != 0; - } - if ( hasMessages ) { - std::this_thread::yield( ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -void T_Console::putLine( T_Text text ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.thread_ ) { - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_PRINT; - o.data = std::move( text ); - pi.sendToThread( std::move( o ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -void T_Console::setPrompt( T_Text prompt ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.thread_ ) { - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_SETPROMPT; - o.data = std::move( prompt ); - pi.sendToThread( std::move( o ) ); - } -} - -void T_Console::setExitLine( T_String const& line ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.thread_ ) { - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_SETEXIT; - o.data = line; - pi.sendToThread( std::move( o ) ); - } -} - -bool T_Console::getLine( T_String& line ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.state_ == pi.C_INPUT_READY && pi.line_ != "\001" ) { - line = pi.line_; - pi.line_ = T_String::Pooled( "\001" ); - - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_SETMODE; - o.data = E_ConsoleInteractionMode::OUTPUT; - pi.sendToThread( std::move( o ) ); - return true; - } - return false; -} - -/*----------------------------------------------------------------------------*/ - -void T_Console::setShortcut( E_ConsoleKey key , T_String const& value ) -{ - assert( key >= E_ConsoleKey::F1 ); - auto& pi( p< T_ConsolePrivate_ >( ) ); - const int index( int( key ) - int( E_ConsoleKey::F1 ) ); - if ( pi.thread_ ) { - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_SETSHORTCUT; - o.data = std::make_pair< int , T_String >( int( index ) , T_String( value ) ); - pi.sendToThread( std::move( o ) ); - } else { - pi.shortcuts_[ index ] = value; - } -} - -T_Array< T_String > T_Console::getShortcuts( ) -{ - wait( ); - auto& pi( p< T_ConsolePrivate_ >( ) ); - T_Array< T_String > shortcuts( NbShortcuts ); - for ( auto i = 0 ; i < NbShortcuts ; i ++ ) { - shortcuts.add( pi.shortcuts_[ i ] ); - } - return shortcuts; -} - -/*----------------------------------------------------------------------------*/ - -uint32_t T_Console::maxHistorySize( ) const -{ - return p< T_ConsolePrivate_ >( ).maxHistory_; -} - -T_Array< T_String > T_Console::history( ) -{ - wait( ); - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.state_ == pi.C_INPUT ) { - throw X_InvalidConsoleState( ); - } - - const uint32_t hs( pi.history_.size( ) ); - if ( hs == pi.historyPos_ + 1 ) { - return pi.history_; - } - - T_Array< T_String > copy( hs ); - for ( uint32_t i = 0 ; i < hs ; i ++ ) { - copy.add( pi.history_[ ( pi.historyPos_ + i ) % hs ] ); - } - return copy; -} - - -void T_Console::maxHistorySize( uint32_t mhs ) -{ - assert( mhs > 0 ); - wait( ); - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.state_ == pi.C_INPUT ) { - throw X_InvalidConsoleState( ); - } - if ( isActive( ) ) { - T_ConsoleControl_ c; - c.type = T_ConsoleControl_::C_SETHISTSIZE; - c.data = mhs; - pi.sendToThread( std::move( c ) ); - } else { - pi.setHistorySize( mhs ); - } -} - -void T_Console::history( T_Array< T_String > const& lines ) -{ - wait( ); - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.state_ == pi.C_INPUT ) { - throw X_InvalidConsoleState( ); - } - if ( isActive( ) ) { - T_ConsoleControl_ c; - c.type = T_ConsoleControl_::C_SETHISTORY; - c.data = lines; - pi.sendToThread( std::move( c ) ); - } else { - T_Array< T_String > lcopy( lines ); - pi.setHistory( lcopy ); - } -} - -/*----------------------------------------------------------------------------*/ - -void T_Console::setProgressInfo( T_Text info ) -{ - auto& pi( p< T_ConsolePrivate_ >( ) ); - if ( pi.thread_ ) { - T_ConsoleControl_ o; - o.type = T_ConsoleControl_::C_SETPROGRESS; - o.data = std::move( info ); - pi.sendToThread( std::move( o ) ); - } -} - -bool T_Console::wasInterrupted( ) const -{ - return p< T_ConsolePrivate_ >( ).state_ == T_ConsolePrivate_::C_INTERRUPTED; -} diff --git a/src/ConsoleLogWriter.cc b/src/ConsoleLogWriter.cc deleted file mode 100644 index e59d979..0000000 --- a/src/ConsoleLogWriter.cc +++ /dev/null @@ -1,83 +0,0 @@ -#include -using namespace lw; - - -namespace { - -char const* const V_Name_ = "console"; -inline T_String Name_( ) { return T_String::Pooled( V_Name_ ); } - -} - - -/*= T_ConsoleLogWriterFactory ================================================*/ - -T_ConsoleLogWriterFactory::T_ConsoleLogWriterFactory( T_Console& console ) - : A_LogWriterFactory( Name_( ) ) , console_( console ) -{ } - -RP_LogWriterConfiguration T_ConsoleLogWriterFactory::createConfiguration( T_String const& name ) const -{ - RP_LogWriterConfiguration p( new T_LogWriterConfiguration( Name_( ) ) ); - p->setName( name ); - return p; -} - -OP_LogWriter T_ConsoleLogWriterFactory::createLogWriter( OP_LogWriterConfiguration&& configuration ) const -{ - T_ConsoleLogWriter* p( new T_ConsoleLogWriter( std::move( configuration ) , console_ ) ); - return OwnRawPointer( p ); -} - - -/*= T_ConsoleLogWriter =======================================================*/ - -T_ConsoleLogWriter::T_ConsoleLogWriter( OP_LogWriterConfiguration&& configuration , T_Console& console ) - : A_LogWriter( std::move( configuration ) ) , console_( console ) -{ } - -void T_ConsoleLogWriter::log( T_LogTimestamp const& timestamp , - E_LogLevel level , T_LogPath const& path , - T_LogStringData const& data , uint32_t size ) -{ - using namespace std::chrono; - - char timeBuffer[ 128 ]; - std::time_t tst( T_LogTimestamp::clock::to_time_t( timestamp ) ); - std::strftime( timeBuffer , 128 , "%Y-%m-%d %H:%M:%S" , std::gmtime( &tst ) ); - const auto ms( ( duration_cast< milliseconds >( timestamp - T_LogTimestamp( ) ) ).count( ) % 1000 ); - - T_TextBuilder sb; - - sb << timeBuffer << '.'; - if ( ms < 100 ) { - sb << '0'; - if ( ms < 10 ) { - sb << '0'; - } - } - sb << ms << ' ' << path.toString( ) << " - " - << E_TextStyle::UNDERLINE; - switch ( level ) { - case E_LogLevel::TRACE: - case E_LogLevel::DEBUG: - case E_LogLevel::INFO: - sb << E_TextColor::CYAN; - break; - case E_LogLevel::NOTICE: - break; - case E_LogLevel::WARNING: - sb << E_TextColor::YELLOW; - break; - case E_LogLevel::CRITICAL: - sb << E_TextStyle::BOLD; - case E_LogLevel::ERROR: - sb << E_TextColor::RED; - break; - } - sb << level; - sb.reset( ); - sb << " - " << T_String( &( (*data) [ 0 ] ) , size ); - - console_.putLine( std::move( sb ) ); -} diff --git a/src/CwdFileLogger.cc b/src/CwdFileLogger.cc deleted file mode 100644 index 452fbeb..0000000 --- a/src/CwdFileLogger.cc +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************/ -/* LOGGING SYSTEM - BUILT-IN LOGGERS - NON-VFS FILE LOG WRITER ****************/ -/******************************************************************************/ - -#include -#include -using namespace lw; - - -namespace { - - -char const* const V_Name_ = "preinit-file"; -inline T_String Name_( ) { return T_String::Pooled( V_Name_ ); } - -bool CFLCPath_( T_SRDParserData const& data ) -{ - auto const& ptok( (*data.input)[ 1 ] ); - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - ( dynamic_cast< T_CWDFileLogWriterCfg* >( lconf ) )->setPath( ptok.stringValue( ) ); - return true; -} - -bool CFLCAppend_( T_SRDParserData const& data ) -{ - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - ( dynamic_cast< T_CWDFileLogWriterCfg* >( lconf ) )->setAppend( true ); - return true; -} - -bool CFLCTruncate_( T_SRDParserData const& data ) -{ - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - ( dynamic_cast< T_CWDFileLogWriterCfg* >( lconf ) )->setAppend( false ); - return true; -} - -} - - -/*= T_CWDFileLogWriterFactory ==================================================*/ - -T_CWDFileLogWriterFactory::T_CWDFileLogWriterFactory( ) - : A_LogWriterFactory( Name_( ) ) -{ } - -RP_LogWriterConfiguration T_CWDFileLogWriterFactory::createConfiguration( T_String const& name ) const -{ - RP_LogWriterConfiguration p( new T_CWDFileLogWriterCfg( ) ); - p->setName( name ); - return p; -} - -OP_LogWriter T_CWDFileLogWriterFactory::createLogWriter( OP_LogWriterConfiguration&& configuration ) const -{ - T_CWDFileLogWriter* p( new T_CWDFileLogWriter( std::move( configuration ) ) ); - return OwnRawPointer( p ); -} - -void T_CWDFileLogWriterFactory::initializeSyntax( T_SRDParserDefs& , T_SRDContext& main ) const -{ - using namespace lw::SRD; - main << ( Rule( ) << "file" << Text( ) << CFLCPath_ ); - main << ( Rule( ) << "append" << CFLCAppend_ ); - main << ( Rule( ) << "truncate" << CFLCTruncate_ ); -} - - -/*= T_CWDFileLogWriterCfg ======================================================*/ - -T_CWDFileLogWriterCfg::T_CWDFileLogWriterCfg( ) - : T_LogWriterConfiguration( Name_( ) ) -{ } - -T_CWDFileLogWriterCfg::T_CWDFileLogWriterCfg( T_CWDFileLogWriterCfg const& source ) - : T_LogWriterConfiguration( source ) , path_( source.path_ ) , - append_( source.append_ ) -{ } - -OP_LogWriterConfiguration T_CWDFileLogWriterCfg::clone( ) -{ - T_CWDFileLogWriterCfg* ptr( new T_CWDFileLogWriterCfg( *this ) ); - return OwnRawPointer( ptr ); -} - -void T_CWDFileLogWriterCfg::check( T_SRDErrors& errors , T_SRDList const& input ) -{ - T_LogWriterConfiguration::check( errors , input ); - if ( !path_ ) { - errors.add( "no file selected" , input[ 0 ] ); - } -} - - -/*= T_CWDFileLogWriter =========================================================*/ - -T_CWDFileLogWriter::T_CWDFileLogWriter( OP_LogWriterConfiguration&& configuration ) - : A_LogWriter( std::move( configuration ) ) -{ } - -void T_CWDFileLogWriter::log( T_LogTimestamp const& timestamp , - E_LogLevel level , T_LogPath const& path , - T_LogStringData const& data , uint32_t size ) -{ - using namespace std::chrono; - - char timeBuffer[ 128 ]; - std::time_t tst( T_LogTimestamp::clock::to_time_t( timestamp ) ); - std::strftime( timeBuffer , 128 , "%Y-%m-%d %H:%M:%S" , std::gmtime( &tst ) ); - const auto ms( ( duration_cast< milliseconds >( timestamp - T_LogTimestamp( ) ) ).count( ) % 1000 ); - - T_StringBuilder sb; - - sb << timeBuffer << '.'; - if ( ms < 100 ) { - sb << '0'; - if ( ms < 10 ) { - sb << '0'; - } - } - sb << ms << ' ' << path.toString( ) << " - " << level << ": "; - sb.append( &( (*data) [ 0 ] ) , size ); - sb << '\n'; - - auto const& cfg( configuration< T_CWDFileLogWriterCfg >( ) ); - auto const& p( cfg.path( ) ); - if ( !file_ ) { - file_ = NewOwned< T_File >( p , cfg.append( ) ? E_FileMode::READ_WRITE : E_FileMode::OVERWRITE ); - if ( !file_ ) { - disable( ); - return; - } - - try { - file_->open( ); - } catch ( X_StreamError const& ) { - disable( ); - file_.clear( ); - return; - } - } - - try { - file_->position( 0 , true ); - file_->write( sb.data( ) , sb.size( ) ); - file_->flush( ); - } catch ( X_StreamError ) { - disable( ); - file_.clear( ); - return; - } -} - diff --git a/src/DynLib.cc b/src/DynLib.cc index 8a255ee..c0de76b 100644 --- a/src/DynLib.cc +++ b/src/DynLib.cc @@ -2,9 +2,9 @@ /* DYNAMIC LIBRARIES **********************************************************/ /******************************************************************************/ -#include -#include -using namespace lw; +#include +#include +using namespace ebcl; #ifdef _WIN32 # error "Not implemented" diff --git a/src/GameLoop.cc b/src/GameLoop.cc deleted file mode 100644 index 5a3930c..0000000 --- a/src/GameLoop.cc +++ /dev/null @@ -1,140 +0,0 @@ -/******************************************************************************/ -/* GAME'S MAIN LOOP ***********************************************************/ -/******************************************************************************/ - -#include -#include -#include -#include -using namespace lw; - - -/*= T_GameLoopPrivate_ =======================================================*/ - -namespace { -struct T_GameLoopPrivate_ -{ - T_Logger logger{ "/core/loop" }; - - OP_Thread thread; - bool active = false; - bool forceShutdown = false; - - T_Mutex mutex; - T_Condition cond; - T_RingBuffer< T_UIMessage > messages{ 64 }; - - /* Game loop */ - void run( ) noexcept; - - /* Wait for the next message, no timeout */ - bool nextMessage( - T_UIMessage& message ) noexcept; -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -inline void T_GameLoopPrivate_::run( ) noexcept -{ - const bool trace( logger.hasLevel( E_LogLevel::TRACE ) ); - logger.debug( ) << "Game loop thread starting"; - - while ( !forceShutdown ) { - T_UIMessage message; - if ( !nextMessage( message ) ) { - continue; - } - - const auto mt( message.type( ) ); - if ( trace ) { - logger.trace( ) << "Got message " << mt; - } - - switch ( mt ) { - - case lw::E_GameUIMessage::QUIT: - // FIXME quit properly - LW::ui( ).putMessage( E_GameLoopMessage::TERMINATED ); - forceShutdown = true; - break; - - default: - logger.debug( ) << "Unhandled message " << mt; - break; - - } - } - - active = false; - logger.debug( ) << "Game loop thread exiting"; -} - -inline bool T_GameLoopPrivate_::nextMessage( - T_UIMessage& message ) noexcept -{ - T_ExclusiveLock lock( mutex ); - cond.wait( lock , [this]() { - return messages.size( ) != 0 || forceShutdown; - } ); - return messages.readNext( message ) - && message.hasMessage( ); -} - - -/*= T_GameLoop ===============================================================*/ - -#define M_PRIVATE_ \ - auto& pi( p< T_GameLoopPrivate_ >( ) ); - -T_GameLoop::T_GameLoop( ) noexcept - : A_PrivateImplementation( new T_GameLoopPrivate_( ) ) -{ } - -bool T_GameLoop::active( ) const noexcept -{ - M_PRIVATE_; - return bool( pi.thread ) && !pi.active; -} - -void T_GameLoop::start( ) noexcept -{ - M_PRIVATE_; - pi.logger.trace( ) << "Starting main loop thread"; - if ( pi.thread ) { - pi.logger.warning( ) - << "The main loop thread is already active?!"; - } - pi.active = true; - pi.thread = NewOwned< T_Thread >( [&]{ - pi.run( ); - } ); -} - -void T_GameLoop::shutdown( ) noexcept -{ - M_PRIVATE_; - if ( !pi.thread ) { - pi.logger.trace( ) - << "The main loop thread is not present"; - return; - } - - if ( pi.active ) { - pi.logger.notice( ) << "Main loop is still active at shutdown!"; - pi.forceShutdown = true; - - T_ExclusiveLock lock( pi.mutex ); - pi.cond.notify_one( ); - } - pi.thread->join( ); - pi.thread.clear( ); -} - -void T_GameLoop::putMessage( T_UIMessage&& message ) noexcept -{ - M_PRIVATE_; - T_ExclusiveLock lock( pi.mutex ); - pi.messages.put( std::move( message ) ); - pi.cond.notify_one( ); -} diff --git a/src/LW.cc b/src/LW.cc deleted file mode 100644 index 2e0db32..0000000 --- a/src/LW.cc +++ /dev/null @@ -1,603 +0,0 @@ -/******************************************************************************/ -/* MAIN CLASS *****************************************************************/ -/******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -using namespace lw; - - -/*= LIBRARY DATA =============================================================*/ - -namespace { -#ifdef LW_BUILD -# include "lib-rom.hh" -#else -const uint8_t lw_library_rom[] = { 0 }; -#endif -} // namespace - - -/*= INTERNALS ================================================================*/ - -namespace { - -/* Command line arguments */ -struct T_CommandLine_ -{ - T_String homePath; - T_Array< T_String > extraPaths; - T_String ui; -}; - -struct T_LWInternals_ -{ - T_LWComponents& components; - - const T_String executablePath_; - T_CommandLine_ arguments_; - - OP_LoggingSystem loggingSystem; - T_Logger lPreinit; - T_Logger logger; - T_Logger lShutdown; - - bool uiInitialised; - - // --------------------------------------------------------------------- - - T_LWInternals_( T_String const& executablePath , - T_LWComponents& components ) noexcept; - - // --------------------------------------------------------------------- - - [[noreturn]] void fatalError( T_Logger& logger , char const* text ); - - /* Load a logging configuration file */ - OP_LoggingConfiguration loadLoggingConfigFile( - T_Logger& logger , - char const* path ) noexcept; - - // --------------------------------------------------------------------- - - /* Pre-initialisation - console, logging, VFS, mods manager */ - void preInit( T_String const& commandLine ); - - OP_LoggingConfiguration getInitialLoggingConfig( ); - void parseCommandLine( - T_String const& commandLine ); - OP_LoggingConfiguration loadPreinitLoggingConfig( ); - OP_LoggingConfiguration getDefaultPreinitLoggingConfig( ); - T_ModsManagerConfiguration getModsManagerConfiguration( ); - - // --------------------------------------------------------------------- - - void init( ); - void run( ); - - // --------------------------------------------------------------------- - - void shutdown( ); - OP_LoggingConfiguration loadShutdownLoggingConfig( ); - OP_LoggingConfiguration getDefaultShutdownLoggingConfig( ); -}; - -} // namespace - -/*----------------------------------------------------------------------------*/ - -inline T_LWInternals_::T_LWInternals_( - T_String const& executablePath , - T_LWComponents& components ) noexcept - : components( components ) , - executablePath_( executablePath ) , - lPreinit( "/core/preinit" ) , - logger( "/core/init" ) , - lShutdown( "/core/shutdown" ) -{ } - -/*----------------------------------------------------------------------------*/ - -void T_LWInternals_::fatalError( T_Logger& logger , char const* message ) -{ - logger.critical( ) << message; - // XXX UI-specific error display if possible - throw X_FatalError( ); -} - -OP_LoggingConfiguration T_LWInternals_::loadLoggingConfigFile( - T_Logger& logger , - char const* const path ) noexcept -{ - T_StringBuilder sb; - sb << path << ".srd"; - const T_String srd( std::move( sb ) ); - sb << path << ".srb"; - const T_String srb( std::move( sb ) ); - - auto& vfs( LW::vfs( ) ); - const bool useSRD( vfs.typeOf( srd ) == E_VFSEntryType::FILE ); - if ( !useSRD && vfs.typeOf( srb ) != E_VFSEntryType::FILE ) { - return {}; - } - T_String const& pstr( useSRD ? srd : srb ); - - auto cfg( LW::logWriters( ).getParserConfiguration( ) ); - T_SRDParser parser( cfg ); - OP_SRDReader reader( ([&]() -> OP_SRDReader { - if ( useSRD ) { - return NewOwned< T_SRDTextReader >( parser ); - } else { - return NewOwned< T_SRDBinaryReader >( parser ); - } - })( ) ); - try { - OP_InputStream input( vfs.read( pstr ) ); - if ( !input ) { - throw X_StreamError( E_StreamError::UNAVAILABLE ); - } - reader->read( pstr , *input ); - return NewOwned< T_LoggingConfiguration >( - std::move( *parser.getData< SP_LoggingConfiguration >( ) ) ); - - } catch ( X_StreamError const& e ) { - logger.warning( ) << "could not load '" - << pstr << "': " << e.what( ); - } catch ( X_SRDErrors const& errors ) { - errors.log( lPreinit ); - } - - return {}; -} - - -/*= PRE-INITIALISATION =======================================================*/ - -void T_LWInternals_::preInit( - T_String const& commandLine ) -{ - // Initialise the console, if we can - components.console = NewOwned< T_Console >( ); - components.console->mode( E_ConsoleMode::OPTIONAL ); - - // Register basic log writers - components.logWriters = NewOwned< T_LogWriterRegistry >( ); - LW::logWriters( ).add< T_CWDFileLogWriterFactory >( ).automatic( false ); - LW::logWriters( ).add< T_ConsoleLogWriterFactory >( LW::console( ) ).automatic( false ); - - // Initialise the logging system with a temporary configuration - loggingSystem = NewOwned< T_LoggingSystem >( - LW::logWriters( ) , - getInitialLoggingConfig( ) ); - - // Parse command line arguments - if ( commandLine ) { - parseCommandLine( commandLine ); - } - - // Initialise the VFS - try { - if ( arguments_.homePath ) { - components.vfs = NewOwned< T_VFS >( arguments_.homePath ); - } else { - components.vfs = NewOwned< T_VFS >( ); - } - } catch ( X_VFSInitialisationFailure const& ) { - fatalError( lPreinit , "Could not initialise the VFS." ); - } - - // Add the VFS-based log writer, then try reconfiguring - LW::logWriters( ).add< T_TextFileLogWriterFactory >( LW::vfs( ) ).automatic( false ); - loggingSystem->reconfigure( loadPreinitLoggingConfig( ) ); - - // Finish configuring the VFS - lPreinit.debug( ) << "Adding install path '" << executablePath_ - << "' to the VFS"; - { - auto ipvfsd( LW::vfs( ).addDriver< T_VFSFilesystemDriver >( - executablePath_ ) ); - if ( !ipvfsd ) { - fatalError( lPreinit , "Could not initialise the VFS." ); - } else { - ipvfsd.automatic( false ); - } - } - const uint32_t nExtraPaths( arguments_.extraPaths.size( ) ); - for ( uint32_t i = 0 ; i < nExtraPaths ; i ++ ) { - auto const& path( arguments_.extraPaths[ i ] ); - lPreinit.trace( ) << "Adding extra path '" << path << "' to the VFS"; - auto vfsd( LW::vfs( ).addDriver< T_VFSFilesystemDriver >( path ) ); - if ( vfsd ) { - vfsd.automatic( false ); - } else { - lPreinit.warning( ) << "unable to add directory '" - << path << "' to the VFS"; - } - } - lPreinit.debug( ) << "Adding library data to the VFS"; - LW::vfs( ).addDriver( LW::getLibData( ) ).automatic( false ); - - // Create the global preprocessor configuration - lPreinit.trace( ) << "Creating SRD preprocessor configuration"; - components.ppConfig = NewOwned< T_SRDPreprocessorConfig >( ); - components.ppConfig->addBuiltinCommands( ); - components.ppConfig->addVFSCommands( *components.vfs ); - - // Initialise the mods manager - lPreinit.trace( ) << "Initialising mods manager"; - components.mods = NewOwned< T_ModsManager >( - getModsManagerConfiguration( ) ); - auto& mods( LW::mods( ) ); - if ( !mods.scanForMods( ) ) { - // TODO later - switch to installer - fatalError( lPreinit , "No mods found" ); - } - if ( !mods.resolveDependencies( ) ) { - // TODO later - switch to installer - fatalError( lPreinit , - "Could not find a valid set of mods " - "matching the current configuration" ); - } - - // Pre-initialise mods - mods.preinitCommon( ); - components.ui = arguments_.ui - ? mods.preinitUIMods( arguments_.ui ) - : mods.preinitUIMods( ); - if ( !components.ui ) { - fatalError( lPreinit , "Unable to start the user interface." ); - } - uiInitialised = false; - - // Create the main loop object - components.gameLoop = NewOwned< T_GameLoop >( ); - lPreinit.trace( ) << "UI & game loop created"; - - // Load main logging configuration - auto lc( loadLoggingConfigFile( lPreinit , "/logging" ) ); - if ( lc ) { - loggingSystem->reconfigure( std::move( lc ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -OP_LoggingConfiguration T_LWInternals_::getInitialLoggingConfig( ) -{ - auto logCfg( NewOwned< T_LoggingConfiguration >( ) ); - logCfg->setMinLevelFor( T_LogPath( ) , E_LogLevel::NOTICE ); - { - const T_String console( T_String::Pooled( "console" ) ); - logCfg->addLogWriter( T_LogPath( ) , console ); - auto writerConfig( LW::logWriters( ) - .get( console ) - ->createConfiguration( console ) ); - logCfg->putLogWriter( OwnRawPointer( writerConfig ) ); - } - { - const T_String tfw( "preinit-file" ); - T_CWDFileLogWriterCfg* writerConfig( - dynamic_cast< T_CWDFileLogWriterCfg *>( - LW::logWriters( ) - .get( tfw ) - ->createConfiguration( tfw ) ) ); - writerConfig->setPath( T_String::Pooled( "legacyworlds-preinit.log" ) ); - writerConfig->setAppend( false ); - logCfg->putLogWriter( OwnRawPointer( writerConfig ) ); - logCfg->addLogWriter( T_LogPath( ) , tfw ); - } - return logCfg; -} - -/*----------------------------------------------------------------------------*/ - -void T_LWInternals_::parseCommandLine( - T_String const& commandLine ) -{ - const T_SRDParserConfig clpConfig( ([]( T_CommandLine_* cl ) { - using namespace lw::SRD; - T_SRDParserDefs defs( "default" ); - - defs << OnStart( [cl]( T_SRDParserData const& d ) -> bool { - *( d.currentData ) = cl; - return true; - } ); - - defs.context( "default" ) - << ( Rule( ) << "ui" << Text( ) - << []( T_SRDParserData const& d ) -> bool { - auto cl( d.currentData->value< T_CommandLine_* >( ) ); - if ( cl->ui ) { - d.errors.add( "duplicate UI identifier" , (*d.input)[ 0 ] ); - } else { - cl->ui = (*d.input)[ 1 ].stringValue( ); - } - return true; - } ) - << ( Rule( ) << "home" << Text( ) - << []( T_SRDParserData const& d ) -> bool { - auto cl( d.currentData->value< T_CommandLine_* >( ) ); - if ( cl->homePath ) { - d.errors.add( "duplicate home directory" , (*d.input)[ 0 ] ); - } else { - cl->homePath = (*d.input)[ 1 ].stringValue( ); - } - return true; - } ) - << ( Rule( ) << "extra-paths" << ( AtLeast( 1 ) << Text( ) ) - << []( T_SRDParserData const& d ) -> bool { - auto cl( d.currentData->value< T_CommandLine_* >( ) ); - auto const& input( *d.input ); - const auto nPaths( input.size( ) ); - for ( uint32_t i = 1 ; i < nPaths ; i ++ ) { - auto const& tok( input[ i ] ); - if ( cl->extraPaths.contains( tok.stringValue( ) ) ) { - d.errors.add( "duplicate data path" , tok ); - } else { - cl->extraPaths.add( tok.stringValue( ) ); - } - } - return true; - } ); - - return T_SRDParserConfig( defs ); - })( &arguments_ ) ); - - T_SRDParser parser( clpConfig ); - T_SRDTextReader reader( parser ); - T_MemoryInputStream input( commandLine.data( ) , commandLine.size( ) ); - try { - reader.read( T_String( "command line" ) , input ); - } catch ( X_SRDErrors const& errors ) { - errors.log( lPreinit ); - fatalError( lPreinit , "Invalid command line arguments" ); - } -} - -/*----------------------------------------------------------------------------*/ - -OP_LoggingConfiguration T_LWInternals_::loadPreinitLoggingConfig( ) -{ - auto rv( loadLoggingConfigFile( lPreinit , "/logging-pre" ) ); - if ( !rv ) { - return getDefaultPreinitLoggingConfig( ); - } - return rv; -} - -OP_LoggingConfiguration T_LWInternals_::getDefaultPreinitLoggingConfig( ) -{ - auto logCfg( NewOwned< T_LoggingConfiguration >( ) ); - { - const T_String console( T_String::Pooled( "console" ) ); - auto writerConfig( LW::logWriters( ) - .get( console ) - ->createConfiguration( console ) ); - writerConfig->setMinLevel( E_LogLevel::NOTICE ); - logCfg->putLogWriter( OwnRawPointer( writerConfig ) ); - logCfg->addLogWriter( T_LogPath( ) , console ); - } - { - const T_String tfw( "text-file" ); - T_TextFileLogWriterCfg* writerConfig( - dynamic_cast< T_TextFileLogWriterCfg *>( - LW::logWriters( ) - .get( tfw ) - ->createConfiguration( tfw ) ) ); - writerConfig->setMinLevel( E_LogLevel::INFO ); - writerConfig->setPath( "/preinit.log" ); - writerConfig->setAppend( false ); - logCfg->putLogWriter( OwnRawPointer( writerConfig ) ); - logCfg->addLogWriter( T_LogPath( ) , tfw ); - } - return logCfg; -} - -/*----------------------------------------------------------------------------*/ - -T_ModsManagerConfiguration T_LWInternals_::getModsManagerConfiguration( ) -{ - using T_MMC = T_ModsManagerConfiguration; - using SP_MMC = SP_ModsManagerConfiguration; - - const T_String mmcfgf( "/mods.srd" ); - auto& vfs( LW::vfs( ) ); - if ( vfs.typeOf( mmcfgf ) == E_VFSEntryType::FILE ) { - auto pconf( T_MMC::GetParserConfig( ) ); - T_SRDParser parser( pconf ); - T_SRDTextReader reader( parser ); - try { - OP_InputStream input( vfs.read( mmcfgf ) ); - if ( !input ) { - throw X_StreamError( E_StreamError::UNAVAILABLE ); - } - reader.read( mmcfgf , *input ); - return std::move( *parser.getData< SP_MMC >( ) ); - - } catch ( X_StreamError const& e ) { - lPreinit.warning( ) << "could not load '" << mmcfgf << "': " - << e.what( ); - } catch ( X_SRDErrors const& errors ) { - errors.log( lPreinit ); - } - } - lPreinit.debug( ) << "Using default mods configuration"; - return T_MMC::DefaultConfiguration( ); -} - - -/*= INITIALISATION ===========================================================*/ - -void T_LWInternals_::init( ) -{ - // Initialise all the mods - const uint32_t nLoaded( components.mods->modsCount( ) ); - uint32_t initialised = 0; - components.mods->initialise( - [&]( RPC_ModInfo mi ) -> F_UpdateInitProgress { - const T_ProgressInfoPart main{ - ([&](){ - T_StringBuilder sb( "Initializing mod " ); - sb << mi->identifier.name; - return T_String{ std::move( sb ) }; - })( ) , initialised + 1 , nLoaded + 2 - }; - initialised ++; - components.ui->setInitProgress( - T_ProgressInfo{ main } ); - - return [&]( T_ProgressInfoPart part ) { - components.ui->setInitProgress( - T_ProgressInfo{ main , part } ); - }; - } ); - - // Initialise UI - const T_ProgressInfoPart uiInitMain{ - T_String( "Initializing user interface" ) , - initialised + 1 , nLoaded + 2 - }; - components.ui->setInitProgress( T_ProgressInfo{ uiInitMain } ); - if ( ! components.ui->init( [&]( T_ProgressInfoPart part ) { - components.ui->setInitProgress( - T_ProgressInfo{ uiInitMain , part } ); - }) ) { - fatalError( logger , "Failed to initialize user interface" ); - } - uiInitialised = true; - - // Start game loop - components.gameLoop->start( ); -} - -/*FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME*/ - -void T_LWInternals_::run( ) -{ - components.ui->run( ); -} - - -/*= SHUTDOWN =================================================================*/ - -void T_LWInternals_::shutdown( ) -{ - lShutdown.trace( ) << "Starting shutdown"; - - // Shutdown game loop if it's still active - if ( components.gameLoop ) { - components.gameLoop->shutdown( ); - } - - // If the UI is present and initialised, shut it down - if ( components.ui && uiInitialised ) { - components.ui->shutdown( ); - uiInitialised = false; - } - - // Shut down mods - if ( components.mods ) { - components.mods->shutdown( ); - } - - // Reset logging configuration - lShutdown.trace( ) << "Resetting logger configuration"; - loggingSystem->reconfigure( loadShutdownLoggingConfig( ) ); - - // Terminate the UI - if ( components.ui ) { - components.ui->postshutdown( ); - components.ui.clear( ); - components.gameLoop.clear( ); - lShutdown.trace( ) << "UI and game loop terminated"; - } - - // Clear mods - if ( components.mods ) { - components.mods->unload( ); - components.mods.clear( ); - lShutdown.trace( ) << "Mods unloaded"; - } - - // Clear remaining components - lShutdown.trace( ) << "Terminating core components"; - components.ppConfig.clear( ); - loggingSystem.clear( ); - components.logWriters.clear( ); - components.console.clear( ); - components.vfs.clear( ); -} - -/*----------------------------------------------------------------------------*/ - -OP_LoggingConfiguration T_LWInternals_::loadShutdownLoggingConfig( ) -{ - auto rv( loadLoggingConfigFile( lShutdown , "/logging-post" ) ); - if ( !rv ) { - return getDefaultShutdownLoggingConfig( ); - } - return rv; -} - -OP_LoggingConfiguration T_LWInternals_::getDefaultShutdownLoggingConfig( ) -{ - auto logCfg( NewOwned< T_LoggingConfiguration >( ) ); - { - const T_String console( T_String::Pooled( "console" ) ); - auto writerConfig( LW::logWriters( ) - .get( console ) - ->createConfiguration( console ) ); - writerConfig->setMinLevel( E_LogLevel::NOTICE ); - logCfg->putLogWriter( OwnRawPointer( writerConfig ) ); - logCfg->addLogWriter( T_LogPath( ) , console ); - } - { - const T_String tfw( "text-file" ); - T_TextFileLogWriterCfg* writerConfig( - dynamic_cast< T_TextFileLogWriterCfg *>( - LW::logWriters( ) - .get( tfw ) - ->createConfiguration( tfw ) ) ); - writerConfig->setMinLevel( E_LogLevel::INFO ); - writerConfig->setPath( "/shutdown.log" ); - writerConfig->setAppend( false ); - logCfg->putLogWriter( OwnRawPointer( writerConfig ) ); - logCfg->addLogWriter( T_LogPath( ) , tfw ); - } - return logCfg; -} - - -/*= MAIN CLASS ===============================================================*/ - -LW* LW::instance_ = nullptr; - -LW::LW( T_String const& commandLine , T_String const& executablePath ) -{ - assert( instance_ == nullptr ); - instance_ = this; - T_LWInternals_ pi( executablePath , components ); - try { - pi.preInit( commandLine ); - pi.init( ); - pi.run( ); - } catch ( X_FatalError const& ) { - pi.shutdown( ); - components.~T_LWComponents( ); - instance_ = nullptr; - throw; - } - pi.shutdown( ); - instance_ = nullptr; -} - -OP_VFSDriver LW::getLibData( ) noexcept -{ - return NewOwned< T_VFSRomDriver >( - lw_library_rom , sizeof( lw_library_rom ) ); -} diff --git a/src/Log.cc b/src/Log.cc deleted file mode 100644 index 20c65d5..0000000 --- a/src/Log.cc +++ /dev/null @@ -1,1041 +0,0 @@ -/******************************************************************************/ -/* LOGGING SYSTEM *************************************************************/ -/******************************************************************************/ - - -#include -#include -using namespace lw; - - -/*= IMPLEMENTATION CLASSES ===================================================*/ - -namespace { - -struct T_LoggerPrivate_ -{ - T_LogPath path_; - bool connected_; - uint32_t pathIndex_; - E_LogLevel minLevel_; - E_LogLevel maxLevel_; - - T_LoggerPrivate_( T_LogPath&& path ); - T_LoggerPrivate_( T_LoggerPrivate_ const& other ); - ~T_LoggerPrivate_( ); - - void connect( ); -}; - -struct T_LoggingSystemPrivate_ -{ - struct T_LogEntry - { - T_LogTimestamp time; - E_LogLevel level; - uint32_t path; - T_LogStringData string; - uint32_t size; - - T_LogEntry( ) = default; - - T_LogEntry( E_LogLevel level , uint32_t path , - T_LogStringData&& string , uint32_t size ); - - T_LogEntry( T_LogEntry const& ) = delete; - T_LogEntry( T_LogEntry&& ) noexcept = default; - - T_LogEntry& operator =( T_LogEntry const& ) = delete; - T_LogEntry& operator =( T_LogEntry&& ) noexcept = default; - }; - - static constexpr uint32_t C_MAX_REUSE_SIZE = 256; - static constexpr uint32_t C_MAX_REUSE_QUANTITY = 64; - - static T_LoggingSystemPrivate_ * instance_; - static T_Mutex loggersMutex_; - static T_Array< T_LoggerPrivate_ * > loggers_; - - RP_LoggingSystem main_; - - T_LogWriterRegistry const& registry_; - OP_LoggingConfiguration config_; - T_Array< OP_LogWriter > writers_; - - OP_Thread thread_; - - T_Mutex queueMutex_; - T_Condition queueCond_; - bool exit_; - T_RingBuffer< T_LogEntry > queue_; - T_Array< T_LogStringData > freeList_; - T_Array< T_LogPath > paths_; - T_Array< uint32_t > pathRefCount_; - - // --------------------------------------------------------------------- - - T_LoggingSystemPrivate_( - RP_LoggingSystem main , - T_LogWriterRegistry const& registry , - OP_LoggingConfiguration&& config ); - ~T_LoggingSystemPrivate_( ); - - // --------------------------------------------------------------------- - - void log( E_LogLevel level , uint32_t pathIndex , char const* data , uint32_t size ); - - void initLogWriters( ); - - // --------------------------------------------------------------------- - - void startLoggingThread( ); - void stopLoggingThread( ); - void expandQueue( ); - - // --------------------------------------------------------------------- - - void loggingThread( ); - void writeEntry( T_LogEntry const& entry ); -}; -} - - -/*= E_LogLevel ===============================================================*/ - -T_StringBuilder& lw::operator<< ( T_StringBuilder& sb , E_LogLevel level ) -{ - switch ( level ) { - case E_LogLevel::TRACE: sb << "trace"; break; - case E_LogLevel::DEBUG: sb << "debug"; break; - case E_LogLevel::INFO: sb << "info"; break; - case E_LogLevel::NOTICE: sb << "notice"; break; - case E_LogLevel::WARNING: sb << "warning"; break; - case E_LogLevel::ERROR: sb << "error"; break; - case E_LogLevel::CRITICAL: sb << "critical"; break; - } - return sb; -} - - -/*= T_LogPath ================================================================*/ - -T_LogPath::T_LogPath( ) - : path_( 1 ) , valid_( true ) -{ } - -T_LogPath::T_LogPath( T_Array< T_String > const& path ) - : path_( path ) , valid_( checkValid( ) ) -{ } - -T_LogPath::T_LogPath( T_Array< T_String >&& path ) - : path_( std::move( path ) ) , valid_( checkValid( ) ) -{ } - -T_LogPath::T_LogPath( std::initializer_list< char const* > arguments ) - : path_( arguments.size( ) ) -{ - for ( char const* arg : arguments ) { - path_.addNew( T_String::Pooled( arg ) ); - } - valid_ = checkValid( ); -} - -/*----------------------------------------------------------------------------*/ - -T_LogPath T_LogPath::FromString( T_String const& string ) -{ - T_StringIterator it( string ); - T_Array< T_String > pieces; - uint32_t pieceStart( 0 ); - bool atStart( true ); - bool afterSlash( false ); - bool valid( true ); - - while ( !it.atEnd( ) ) { - const T_Character c( it ); - - if ( c == '/' ) { - if ( !( atStart || afterSlash ) ) { - pieces.add( string.range( pieceStart , it.index( ) - 1 ) ); - afterSlash = true; - } - } else { - if ( atStart ) { - atStart = false; - afterSlash = true; - } - if ( afterSlash ) { - afterSlash = false; - pieceStart = it.index( ); - } - valid = valid && !c.isControl( ); - } - - it.next( ); - } - if ( !( atStart || afterSlash ) ) { - pieces.add( string.range( pieceStart , it.index( ) ) ); - } - - if ( pieces.size( ) == 0 ) { - return T_LogPath( ); - } - - T_LogPath lp( pieces.size( ) , valid ); - lp.path_.addAll( std::move( pieces ) ); - return lp; -} - -/*----------------------------------------------------------------------------*/ - -T_LogPath T_LogPath::parent( ) const -{ - const auto sz( size( ) ); - if ( sz > 1 ) { - if ( valid_ ) { - T_LogPath lp( sz - 1 , true ); - for ( uint32_t i = 0 ; i < sz - 1 ; i ++ ) { - lp.path_.add( path_[ i ] ); - } - return lp; - } else { - return T_LogPath( path_.copyRange( 0 , sz - 2 ) ); - } - } else { - return T_LogPath( ); - } -} - -T_LogPath T_LogPath::child( T_String const& name ) const -{ - const auto sz( size( ) ); - T_LogPath lp( sz + 1 , valid_ && checkName( name ) ); - lp.path_.addAll( path_ ); - lp.path_.add( name ); - return lp; -} - -/*----------------------------------------------------------------------------*/ - -T_String T_LogPath::toString( ) const -{ - const auto sz( size( ) ); - if ( sz ) { - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < sz ; i ++ ) { - sb << '/' << path_[ i ]; - } - return T_String( std::move( sb ) ); - } else { - return T_String::Pooled( "/" ); - } -} - -/*----------------------------------------------------------------------------*/ - -bool T_LogPath::isChildOf( T_LogPath const& other ) const -{ - const auto os( other.size( ) ); - if ( size( ) <= os ) { - return false; - } - for ( uint32_t i = 0 ; i < os ; i ++ ) { - if ( path_[ i ] != other.path_[ i ] ) { - return false; - } - } - return true; -} - -bool T_LogPath::operator ==( T_LogPath const& other ) const -{ - if ( this == &other ) { - return true; - } - - const auto ms( size( ) ); - if ( ms != other.size( ) ) { - return false; - } - for ( uint32_t i = 0 ; i < ms ; i ++ ) { - if ( path_[ i ] != other.path_[ i ] ) { - return false; - } - } - return true; -} - -/*----------------------------------------------------------------------------*/ - -T_LogPath::T_LogPath( uint32_t size , bool valid ) - : path_( size ) , valid_( valid ) -{ } - -bool T_LogPath::checkValid( ) const -{ - const auto s( path_.size( ) ); - for ( uint32_t i = 0 ; i < s ; i ++ ) { - if ( !checkName( path_[ i ] ) ) { - return false; - } - } - return true; -} - -bool T_LogPath::checkName( T_String const& name ) -{ - if ( !name ) { - return false; - } - - T_StringIterator it( name ); - while ( !it.atEnd( ) ) { - const T_Character c( it ); - it.next( ); - if ( c.isControl( ) || c == '/' ) { - return false; - } - } - return true; -} - -/*----------------------------------------------------------------------------*/ - -M_DEFINE_HASH( T_LogPath ) -{ - const auto sz( item.size( ) ); - uint32_t hash = 1; - for ( uint32_t i = 0 ; i < sz ; i ++ ) { - hash = hash * 47 + ComputeHash( item[ i ] ); - } - return hash; -} - - -/*= T_LogWriterConfiguration ================================================*/ - -T_LogWriterConfiguration::T_LogWriterConfiguration( T_String const& type ) - : writerType_( type ) -{ } - -T_LogWriterConfiguration::~T_LogWriterConfiguration( ) -{ } - -OP_LogWriterConfiguration T_LogWriterConfiguration::clone( ) -{ - RP_LogWriterConfiguration p( new T_LogWriterConfiguration( *this ) ); - return OwnRawPointer( p ); -} - -void T_LogWriterConfiguration::check( T_SRDErrors& errors , T_SRDList const& input ) -{ - if ( minLevel_ > maxLevel_ ) { - errors.add( "minimal level is higher than maximal level" , input[ 1 ] ); - } -} - - -/*= A_LogWriterFactory ==========================================================*/ - -void A_LogWriterFactory::initializeSyntax( T_SRDParserDefs& , T_SRDContext& ) const -{ } - - -/*= T_LogWriterRegistryPrivate_ =================================================*/ - -namespace { -struct T_LogWriterRegistryPrivate_ -{ - T_ObjectTable< T_String , OP_LogWriterFactory > factories_{ - []( OP_LogWriterFactory const& f ) -> T_String const& { - return f->name( ); - } , 128 , 128 - }; - - T_RegisteredItem::SP_Unregister uf_{ - NewShared< T_RegisteredItem::F_Unregister >( - [this]( void* data ) { - factories_.remove( *reinterpret_cast< T_String* >( data ) ); - } - ) - }; - -}; -} // namespace - - -/*= T_LogWriterRegistry =========================================================*/ - -T_LogWriterRegistry::T_LogWriterRegistry( ) noexcept - : A_PrivateImplementation( new T_LogWriterRegistryPrivate_( ) ) -{ } - -T_RegisteredItem T_LogWriterRegistry::add( OP_LogWriterFactory&& factory ) noexcept -{ - auto& pi( p< T_LogWriterRegistryPrivate_ >( ) ); - if ( !factory || pi.factories_.contains( factory->name( ) ) ) { - return T_RegisteredItem( ); - } - - auto const& fn( factory->name( ) ); - pi.factories_.add( std::move( factory ) ); - return T_RegisteredItem( pi.uf_ , new T_String( fn ) ); -} - -RPC_LogWriterFactory T_LogWriterRegistry::get( T_String const& name ) const noexcept -{ - auto& pi( ); - OP_LogWriterFactory const* ptr( - p< T_LogWriterRegistryPrivate_ >( ).factories_.get( name ) ); - return ptr ? ptr->get( ) : nullptr; -} - -/*----------------------------------------------------------------------------*/ - -namespace { - -using T_PathCfg_ = std::pair< SP_LoggingConfiguration , T_LogPath >; - -// Start the parser -bool PCStart_( T_SRDParserData const& data ) -{ - *( data.currentData ) = NewShared< T_LoggingConfiguration >( ); - return true; -} - -// Entering a path configuration -bool PCEnterPath_( T_SRDParserData const& data ) -{ - auto const& tok( (*data.input)[ 0 ] ); - const T_LogPath lp( tok.type( ) == E_SRDTokenType::WORD - ? T_LogPath( ) - : T_LogPath::FromString( tok.stringValue( ) ) ); - auto cfg( data.currentData->value< SP_LoggingConfiguration >( ) ); - if ( !lp.isValid( ) ) { - data.errors.add( "invalid logging path" , tok ); - } else { - if ( lp.size( ) && cfg->isPathConfigured( lp ) ) { - data.errors.add( "duplicate path entry" , tok ); - } - } - - if ( !cfg->isPathConfigured( lp ) ) { - cfg->addPathConfiguration( lp ); - } - *( data.targetData ) = std::make_pair< SP_LoggingConfiguration , T_LogPath >( - SP_LoggingConfiguration( std::move( cfg ) ) , - T_LogPath( std::move( lp ) ) ); - return true; -} - -// End of path configuration - make sure it's valid -bool PCCheckPath_( T_SRDParserData const& data ) -{ - auto const& input( *data.input ); - T_PathCfg_& pcfg( data.currentData->value< T_PathCfg_ >( ) ); - if ( pcfg.first->logWritersFor( pcfg.second ).size( ) == 0 ) { - data.errors.add( "no loggers for this path" , input[ 1 ] ); - } - const auto min( pcfg.first->minLevelFor( pcfg.second ) ); - const auto max( pcfg.first->maxLevelFor( pcfg.second ) ); - if ( min > max ) { - data.errors.add( "minimal level is higher than maximal level" , input[ 1 ] ); - } - return true; -} - -// Set the minimal or maximal log level for a path -bool PCPathLevel_( T_SRDParserData const& data ) -{ - auto const& input( *data.input ); - T_SRDEnum const& levels( *data.config.enums.get( T_String::Pooled( "log-level" ) ) ); - const E_LogLevel level( (E_LogLevel) levels[ input[ 1 ].stringValue( ) ] ); - - T_PathCfg_& pcfg( data.targetData->value< T_PathCfg_ >( ) ); - if ( input[ 0 ].stringValue( ) == "min-level" ) { - pcfg.first->setMinLevelFor( pcfg.second , level ); - } else { - pcfg.first->setMaxLevelFor( pcfg.second , level ); - } - - return true; -} - -// Add a logger to a path -bool PCPathLogger_( T_SRDParserData const& data ) -{ - auto const& input( *data.input ); - T_String const& logger( input[ 1 ].stringValue( ) ); - T_PathCfg_& pcfg( data.targetData->value< T_PathCfg_ >( ) ); - if ( pcfg.first->hasLogWriter( pcfg.second , logger ) ) { - data.errors.add( "duplicate logger for this path" , input[ 1 ] ); - } else { - pcfg.first->addLogWriter( pcfg.second , logger ); - } - return true; -} - -// Prepare for a logger's configuration -bool PCEnterLogger_( T_SRDParserData const& data , OP_LogWriterFactory const& factory ) -{ - auto const& input( *data.input ); - auto cfg( data.currentData->value< SP_LoggingConfiguration >( ) ); - - auto lconf( factory->createConfiguration( input[ 1 ].stringValue( ) ) ); - if ( cfg->hasLogWriter( input[ 1 ].stringValue( ) ) ) { - data.errors.add( "duplicate logger" , input[ 1 ] ); - } - *( data.targetData ) = lconf; - return true; -} - -// Check a logger's configuration and add it to the list -bool PCCheckLogger_( T_SRDParserData const& data ) -{ - auto lconf( data.currentData->value< RP_LogWriterConfiguration >( ) ); - auto cfg( data.targetData->value< SP_LoggingConfiguration >( ) ); - lconf->check( data.errors , *data.input ); - if ( cfg->hasLogWriter( lconf->name( ) ) ) { - delete lconf; - } else { - cfg->putLogWriter( OwnRawPointer( lconf ) ); - } - return true; -} - -// Set the minimal or maximal log level for a logger -bool PCLoggerLevel_( T_SRDParserData const& data ) -{ - auto const& input( *data.input ); - T_SRDEnum const& levels( *data.config.enums.get( T_String::Pooled( "log-level" ) ) ); - const E_LogLevel level( (E_LogLevel) levels[ input[ 1 ].stringValue( ) ] ); - - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - if ( input[ 0 ].stringValue( ) == "min-level" ) { - lconf->setMinLevel( level ); - } else { - lconf->setMaxLevel( level ); - } - - return true; -} - -}; - -T_SRDParserConfig T_LogWriterRegistry::getParserConfiguration( ) noexcept -{ - auto& pi( p< T_LogWriterRegistryPrivate_ >( ) ); - assert( pi.factories_.size( ) != 0 && "no registered factories" ); - - using namespace lw::SRD; - - T_SRDParserDefs defs( "default" ); - defs << OnStart( PCStart_ ); - - defs.enumeration( "log-level" ) - << "trace" << "debug" << "info" << "notice" - << "warning" << "error" << "critical"; - - defs.context( "default" ) - << ( Rule( ) << "paths" << EnterContext( "paths" ) ) - << ( Rule( ) << "loggers" << EnterContext( "loggers" ) ); - - defs.context( "paths" ) - << ( Rule( ) << ( Alt( ) << String( ) << Word( "root" ) ) - << EnterContext( "path" ) - << OnEnter( PCEnterPath_ ) << OnExit( PCCheckPath_ ) ); - defs.context( "path" ) - << ( Rule( ) << "min-level" << Enum( "log-level" ) << PCPathLevel_ ) - << ( Rule( ) << "max-level" << Enum( "log-level" ) << PCPathLevel_ ) - << ( Rule( ) << "logger" << Word( ) << PCPathLogger_ ); - - T_Array< OP_LogWriterFactory > const& factories( pi.factories_.values( ) ); - const auto nf( factories.size( ) ); - for ( uint32_t i = 0 ; i < nf ; i ++ ) { - OP_LogWriterFactory const& f( factories[ i ] ); - - T_StringBuilder sb( "logger-" ); - sb << f->name( ); - const T_String ctxName( std::move( sb ) ); - - defs.context( "loggers" ) - << ( Rule( ) << Word( f->name( ) ) << Word( ) - << EnterContext( ctxName ) - << OnEnter( [&f]( auto const& data ) { - return PCEnterLogger_( data , f ); - } ) - << OnExit( PCCheckLogger_ ) ); - - auto& ctx( defs.context( ctxName ) ); - ctx << ( Rule( ) << "min-level" << Enum( "log-level" ) << PCLoggerLevel_ ); - ctx << ( Rule( ) << "max-level" << Enum( "log-level" ) << PCLoggerLevel_ ); - f->initializeSyntax( defs , ctx ); - } - - return T_SRDParserConfig( defs ); -} - - -/*= T_LoggingConfiguration ===================================================*/ - -T_LoggingConfiguration::T_PathInfo_::T_PathInfo_( T_LogPath const& path ) - : path( path ) , writers( 8 ) -{ } - -/*----------------------------------------------------------------------------*/ - -T_LoggingConfiguration::T_LoggingConfiguration( ) - : writers_( - []( OP_LogWriterConfiguration const& cfg ) -> T_String const& { - return cfg->name( ); - } , 128 , 128 ) , - paths_( - []( T_PathInfo_ const& pi ) -> T_LogPath const& { - return pi.path; - } , 128 , 128 ) -{ - paths_.add( T_PathInfo_( T_LogPath( ) ) ); -} - -/*----------------------------------------------------------------------------*/ - -bool T_LoggingConfiguration::hasLogWriter( T_String const& name ) const -{ - return writers_.contains( name ); -} - -void T_LoggingConfiguration::putLogWriter( OP_LogWriterConfiguration&& configuration ) -{ - const bool ok( writers_.add( std::move( configuration ) ) ); - assert( ok ); -} - -T_Array< OP_LogWriterConfiguration > const& T_LoggingConfiguration::logWriters( ) const -{ - return writers_.values( ); -} - -/*----------------------------------------------------------------------------*/ - -bool T_LoggingConfiguration::isPathConfigured( T_LogPath const& path ) const -{ - return paths_.contains( path ); -} - -void T_LoggingConfiguration::addPathConfiguration( T_LogPath const& path ) -{ - const bool ok( paths_.add( T_PathInfo_( path ) ) ); - assert( ok ); -} - -void T_LoggingConfiguration::setMinLevelFor( T_LogPath const& path , E_LogLevel minLevel ) -{ - T_PathInfo_* const pi( paths_.get( path ) ); - assert( pi != nullptr ); - pi->minLevel = minLevel; -} - -void T_LoggingConfiguration::setMaxLevelFor( T_LogPath const& path , E_LogLevel maxLevel ) -{ - T_PathInfo_* const pi( paths_.get( path ) ); - assert( pi != nullptr ); - pi->maxLevel = maxLevel; -} - -bool T_LoggingConfiguration::hasLogWriter( T_LogPath const& path , T_String const& name ) const -{ - T_PathInfo_ const* const pi( paths_.get( path ) ); - assert( pi != nullptr ); - return pi->writers.contains( name ); -} - -void T_LoggingConfiguration::addLogWriter( T_LogPath const& path , T_String const& name ) -{ - T_PathInfo_ * const pi( paths_.get( path ) ); - assert( pi != nullptr ); - assert( !pi->writers.contains( name ) ); - pi->writers.add( name ); -} - -/*----------------------------------------------------------------------------*/ - -T_LoggingConfiguration::T_PathInfo_ const& T_LoggingConfiguration::getPathInfo( - T_LogPath const& path ) const -{ - T_PathInfo_ const* const pi( paths_.get( path ) ); - if ( pi ) { - return *pi; - } - - T_Array< T_PathInfo_ > const& all( paths_.values( ) ); - const auto sz( all.size( ) ); - uint32_t bestMatch( 0 ); - uint32_t bmLength( 0 ); - for ( uint32_t i = 0 ; i < sz ; i ++ ) { - auto const& p( all[ i ] ); - if ( p.path.isParentOf( path ) && p.path.size( ) > bmLength ) { - bmLength = p.path.size( ); - bestMatch = i; - } - } - - return paths_[ bestMatch ]; -} - - -/*= T_LoggingSystemPrivate_ ==================================================*/ - -constexpr uint32_t T_LoggingSystemPrivate_::C_MAX_REUSE_SIZE; -constexpr uint32_t T_LoggingSystemPrivate_::C_MAX_REUSE_QUANTITY; -T_LoggingSystemPrivate_ * T_LoggingSystemPrivate_::instance_ = nullptr; -T_Mutex T_LoggingSystemPrivate_::loggersMutex_; -T_Array< T_LoggerPrivate_ * > T_LoggingSystemPrivate_::loggers_( 32 ); - -/*----------------------------------------------------------------------------*/ - -T_LoggingSystemPrivate_::T_LogEntry::T_LogEntry( E_LogLevel level , - uint32_t path , T_LogStringData&& string , uint32_t size ) - : time( std::chrono::high_resolution_clock::now( ) ) , - level( level ) , path( path ) , string( std::move( string ) ) , - size( size ) -{ } - -/*----------------------------------------------------------------------------*/ - -inline T_LoggingSystemPrivate_::T_LoggingSystemPrivate_( - RP_LoggingSystem main , - T_LogWriterRegistry const& registry , - OP_LoggingConfiguration&& config ) - : main_( main ) , registry_( registry ) , - config_( std::move( config ) ) , writers_( 16 ) , - thread_( ) , queueMutex_( ) , queueCond_( ) , exit_( false ) , - queue_( 16 ) , freeList_( C_MAX_REUSE_QUANTITY ) , - paths_( 8 ) , pathRefCount_( 8 ) -{ - assert( config_ ); - assert( instance_ == nullptr ); - initLogWriters( ); - { - T_ScopeLock lk( loggersMutex_ ); - instance_ = this; - const auto nLoggers( loggers_.size( ) ); - for ( uint32_t i = 0 ; i < nLoggers ; i ++ ) { - loggers_[ i ]->connect( ); - } - } - startLoggingThread( ); -} - -inline T_LoggingSystemPrivate_::~T_LoggingSystemPrivate_( ) -{ - assert( instance_ == this ); - { - T_ScopeLock lk( loggersMutex_ ); - instance_ = nullptr; - const auto nLoggers( loggers_.size( ) ); - for ( uint32_t i = 0 ; i < nLoggers ; i ++ ) { - loggers_[ i ]->connected_ = false; - } - } - stopLoggingThread( ); - writers_.clear( ); -} - -/*----------------------------------------------------------------------------*/ - -void T_LoggingSystemPrivate_::log( E_LogLevel level , uint32_t pathIndex , - char const* data , uint32_t size ) -{ - assert( size ); - assert( pathIndex < paths_.size( ) ); - assert( pathRefCount_[ pathIndex ] > 0 ); - - T_LogStringData lsd; - if ( size > C_MAX_REUSE_SIZE ) { - lsd = NewOwned< T_Buffer< char > >( data , size ); - } - - T_ScopeLock lk( queueMutex_ ); - if ( !lsd ) { - const auto fls( freeList_.size( ) ); - if ( fls == 0 ) { - lsd = NewOwned< T_Buffer< char > >( C_MAX_REUSE_SIZE ); - } else { - lsd = std::move( freeList_[ fls - 1 ] ); - freeList_.remove( fls - 1 ); - } - memcpy( lsd->data( ) , data , size ); - } - - assert( lsd ); - pathRefCount_[ pathIndex ] ++; - queue_.putNew( level , pathIndex , std::move( lsd ) , size ); - queueCond_.notify_one( ); -} - -/*----------------------------------------------------------------------------*/ - -void T_LoggingSystemPrivate_::initLogWriters( ) -{ - auto const& lws( config_->logWriters( ) ); - const auto lwc( lws.size( ) ); - writers_.ensureCapacity( lwc ); - for ( uint32_t i = 0 ; i < lwc ; i ++ ) { - const RPC_LogWriterFactory factory( registry_.get( lws[ i ]->writerType( ) ) ); - writers_.add( factory->createLogWriter( lws[ i ]->clone( ) ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -void T_LoggingSystemPrivate_::startLoggingThread( ) -{ - assert( !thread_ ); - exit_ = false; - thread_ = NewOwned< T_Thread >( [this]() { loggingThread( ); } ); -} - -void T_LoggingSystemPrivate_::stopLoggingThread( ) -{ - assert( thread_ ); - - { - T_ScopeLock lk( queueMutex_ ); - exit_ = true; - } - queueCond_.notify_one( ); - thread_->join( ); - thread_ = T_OwnPtr< T_Thread >( ); -} - -/*----------------------------------------------------------------------------*/ - -void T_LoggingSystemPrivate_::loggingThread( ) -{ - T_Array< T_LogEntry > entries( queue_.growth( ) ); - T_ExclusiveLock lock( queueMutex_ ); - do { - T_LogEntry entry; - - queueCond_.wait( lock , [this]( ) { - return exit_ || queue_.size( ); - } ); - if ( queue_.readAll( entries ) ) { - lock.unlock( ); - } - - uint32_t nEntries( 0 ); - while ( nEntries < entries.size( ) ) { - const auto nne( entries.size( ) ); - for ( uint32_t i = nEntries ; i < nne ; i ++ ) { - writeEntry( entries[ i ] ); - } - - // Try to read new entries - nEntries = nne; - lock.lock( ); - if ( queue_.readAll( entries ) ) { - lock.unlock( ); - } - } - - // Decrease path reference counters - for ( uint32_t i = 0 ; i < nEntries ; i ++ ) { - pathRefCount_[ entries[ i ].path ] --; - } - - // Return string data buffers to the free list - for ( uint32_t i = 0 ; i < nEntries - && freeList_.size( ) < C_MAX_REUSE_QUANTITY ; i ++ ) { - auto& entry( entries[ i ] ); - if ( entry.string->size( ) == C_MAX_REUSE_SIZE ) { - freeList_.add( std::move( entry.string ) ); - } - } - - entries.clear( ); - } while ( !exit_ ); - lock.unlock( ); -} - -void T_LoggingSystemPrivate_::writeEntry( T_LogEntry const& entry ) -{ - T_LogPath const& path( paths_[ entry.path ] ); - - const E_LogLevel min( config_->minLevelFor( path ) ); - const E_LogLevel max( config_->maxLevelFor( path ) ); - if ( min > entry.level || max < entry.level ) { - return; - } - - const T_Array< T_String > writers( config_->logWritersFor( path ) ); - const auto nw( writers.size( ) ); - const auto nwi( writers_.size( ) ); - for ( uint32_t i = 0 ; i < nw ; i ++ ) { - auto const& name( writers[ i ] ); - for ( uint32_t j = 0 ; j < nwi ; j ++ ) { - auto& writer( writers_[ j ] ); - auto const& cfg( writer->configuration< T_LogWriterConfiguration >( ) ); - if ( cfg.name( ) != name ) { - continue; - } - if ( cfg.maxLevel( ) >= entry.level - && cfg.minLevel( ) <= entry.level ) { - writer->log( entry.time , entry.level , path , - entry.string , entry.size ); - } - break; - } - } -} - - -/*= T_LoggerPrivate_ =========================================================*/ - -inline T_LoggerPrivate_::T_LoggerPrivate_( T_LogPath&& path ) - : path_( std::move( path ) ) , connected_( false ) , - pathIndex_( 0 ) , minLevel_( E_LogLevel::TRACE ) , - maxLevel_( E_LogLevel::CRITICAL ) -{ - T_ScopeLock lk( T_LoggingSystemPrivate_::loggersMutex_ ); - T_LoggingSystemPrivate_::loggers_.add( this ); - if ( T_LoggingSystemPrivate_::instance_ ) { - connect( ); - } -} - -inline T_LoggerPrivate_::T_LoggerPrivate_( T_LoggerPrivate_ const& other ) - : path_( other.path_ ) , connected_( other.connected_ ) , - pathIndex_( other.pathIndex_ ) , minLevel_( other.minLevel_ ) , - maxLevel_( other.maxLevel_ ) -{ - T_ScopeLock lk( T_LoggingSystemPrivate_::loggersMutex_ ); - T_LoggingSystemPrivate_::loggers_.add( this ); - assert( connected_ == bool( T_LoggingSystemPrivate_::instance_ ) ); - if ( T_LoggingSystemPrivate_::instance_ ) { - T_ScopeLock lk2( T_LoggingSystemPrivate_::instance_->queueMutex_ ); - T_LoggingSystemPrivate_::instance_->pathRefCount_[ pathIndex_ ] ++; - } -} - -inline T_LoggerPrivate_::~T_LoggerPrivate_( ) -{ - T_ScopeLock lk( T_LoggingSystemPrivate_::loggersMutex_ ); - assert( connected_ == bool( T_LoggingSystemPrivate_::instance_ ) ); - if ( T_LoggingSystemPrivate_::instance_ ) { - T_ScopeLock lk2( T_LoggingSystemPrivate_::instance_->queueMutex_ ); - T_LoggingSystemPrivate_::instance_->pathRefCount_[ pathIndex_ ] --; - } - T_LoggingSystemPrivate_::loggers_.removeSwap( - T_LoggingSystemPrivate_::loggers_.indexOf( this ) ); -} - -/*----------------------------------------------------------------------------*/ - -void T_LoggerPrivate_::connect( ) -{ - T_LoggingSystemPrivate_ * ins( T_LoggingSystemPrivate_::instance_ ); - connected_ = true; - minLevel_ = ins->config_->minLevelFor( path_ ); - maxLevel_ = ins->config_->maxLevelFor( path_ ); - - T_ScopeLock lk2( ins->queueMutex_ ); - const auto found( ins->paths_.indexOf( path_ ) ); - if ( found != -1 ) { - pathIndex_ = found; - ins->pathRefCount_[ found ] ++; - } else { - const auto empty( ins->pathRefCount_.indexOf( 0 ) ); - if ( empty == -1 ) { - pathIndex_ = ins->paths_.add( path_ ); - ins->pathRefCount_.add( 1 ); - } else { - ins->paths_[ empty ] = path_; - ins->pathRefCount_[ empty ] = 1; - } - } -} - - -/*= T_Logger =================================================================*/ - -T_Logger::T_Logger( T_LogPath path ) - : A_PrivateImplementation( new T_LoggerPrivate_( std::move( path ) ) ) -{ } - -T_Logger::T_Logger( T_Logger const& other ) - : A_PrivateImplementation( new T_LoggerPrivate_( - other.p< T_LoggerPrivate_ >( ) ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -bool T_Logger::hasLevel( E_LogLevel level ) const -{ - auto const& pi( p< T_LoggerPrivate_ >( ) ); - return pi.connected_ && level >= pi.minLevel_ && level <= pi.maxLevel_; -} - -/*----------------------------------------------------------------------------*/ - -void T_Logger::log( E_LogLevel level , T_String const& string ) -{ - auto const& pi( p< T_LoggerPrivate_ >( ) ); - if ( T_LoggingSystemPrivate_::instance_ && pi.connected_ && string ) { - T_LoggingSystemPrivate_::instance_->log( level , pi.pathIndex_ , - string.data( ) , string.size( ) ); - } -} - -void T_Logger::log( E_LogLevel level , T_StringBuilder const& string ) -{ - auto const& pi( p< T_LoggerPrivate_ >( ) ); - if ( T_LoggingSystemPrivate_::instance_ && pi.connected_ && string ) { - T_LoggingSystemPrivate_::instance_->log( level , pi.pathIndex_ , - string.data( ) , string.size( ) ); - } -} - -void T_Logger::log( E_LogLevel level , char const* string ) -{ - assert( string ); - const auto size( strlen( string ) ); - - auto const& pi( p< T_LoggerPrivate_ >( ) ); - if ( T_LoggingSystemPrivate_::instance_ && pi.connected_ && size ) { - T_LoggingSystemPrivate_::instance_->log( - level , pi.pathIndex_ , string , size ); - } -} - - -/*= T_LoggingSystem ==========================================================*/ - -T_LoggingSystem::T_LoggingSystem( - T_LogWriterRegistry const& registry , - OP_LoggingConfiguration&& config ) - : A_PrivateImplementation( new T_LoggingSystemPrivate_( - this , registry , std::move( config ) ) ) -{ } - -void T_LoggingSystem::reconfigure( OP_LoggingConfiguration&& configuration ) -{ - assert( configuration ); - auto& pi( p< T_LoggingSystemPrivate_>( ) ); - pi.stopLoggingThread( ); - { - T_ScopeLock lk( pi.loggersMutex_ ); - pi.config_ = std::move( configuration ); - - pi.paths_.clear( ); - pi.pathRefCount_.clear( ); - pi.writers_.clear( ); - - pi.initLogWriters( ); - const auto nLoggers( pi.loggers_.size( ) ); - for ( uint32_t i = 0 ; i < nLoggers ; i ++ ) { - pi.loggers_[ i ]->connect( ); - } - } - pi.startLoggingThread( ); -} diff --git a/src/Messages.cc b/src/Messages.cc deleted file mode 100644 index 8012c72..0000000 --- a/src/Messages.cc +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************/ -/* UI<=>GAME MESSAGES *********************************************************/ -/******************************************************************************/ - -#include - -using namespace lw; - -#define M_ENUM_OUT_( Type , Value ) \ - case Type::Value: obj << #Value; break - - -/*= A_GameView ===============================================================*/ - -A_GameView::~A_GameView( ) -{ } - - -/*= A_ViewBuilder ============================================================*/ - -A_ViewBuilder::~A_ViewBuilder( ) -{ } - - -/*= E_GameState ==============================================================*/ - -namespace lw { -M_LSHIFT_OP( T_StringBuilder , E_GameState ) -{ - switch ( value ) { - M_ENUM_OUT_( E_GameState , NO_GAME ); - M_ENUM_OUT_( E_GameState , GAME_PAUSED ); - M_ENUM_OUT_( E_GameState , GAME_SLOW ); - M_ENUM_OUT_( E_GameState , GAME_NORMAL ); - M_ENUM_OUT_( E_GameState , GAME_FAST ); - } - return obj; -} -} // namespace lw - - -/*= E_GameUIMessage ==========================================================*/ - -namespace lw { -M_LSHIFT_OP( T_StringBuilder , E_GameUIMessage ) -{ - switch ( value ) { - M_ENUM_OUT_( E_GameUIMessage , NEW ); - M_ENUM_OUT_( E_GameUIMessage , LOAD ); - M_ENUM_OUT_( E_GameUIMessage , SAVE ); - M_ENUM_OUT_( E_GameUIMessage , STOP ); - M_ENUM_OUT_( E_GameUIMessage , QUIT ); - M_ENUM_OUT_( E_GameUIMessage , ABORT ); - M_ENUM_OUT_( E_GameUIMessage , DELETE ); - M_ENUM_OUT_( E_GameUIMessage , COPY_OR_RENAME ); - M_ENUM_OUT_( E_GameUIMessage , SET_SPEED ); - M_ENUM_OUT_( E_GameUIMessage , STEPS ); - M_ENUM_OUT_( E_GameUIMessage , SET_VIEW ); - M_ENUM_OUT_( E_GameUIMessage , VIEW_DISPLAYED ); - M_ENUM_OUT_( E_GameUIMessage , QUERY ); - M_ENUM_OUT_( E_GameUIMessage , COMMAND ); - } - return obj; -} -} // namespace lw - - -/*= E_GameLoopMessage ========================================================*/ - -namespace lw { -M_LSHIFT_OP( T_StringBuilder , E_GameLoopMessage ) -{ - switch ( value ) { - M_ENUM_OUT_( E_GameLoopMessage , TERMINATED ); - M_ENUM_OUT_( E_GameLoopMessage , PROGRESS ); - M_ENUM_OUT_( E_GameLoopMessage , DONE ); - M_ENUM_OUT_( E_GameLoopMessage , STATE_CHANGED ); - M_ENUM_OUT_( E_GameLoopMessage , VIEW_AVAILABLE ); - M_ENUM_OUT_( E_GameLoopMessage , QUERY_RESPONSE ); - M_ENUM_OUT_( E_GameLoopMessage , COMMAND_OK ); - M_ENUM_OUT_( E_GameLoopMessage , COMMAND_SYNTAX ); - M_ENUM_OUT_( E_GameLoopMessage , COMMAND_ERROR ); - } - return obj; -} -} // namespace lw diff --git a/src/ModInterface.cc b/src/ModInterface.cc deleted file mode 100644 index 8404c9b..0000000 --- a/src/ModInterface.cc +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************/ -/* MODDING SYSTEM INTERFACES **************************************************/ -/******************************************************************************/ - -#include -using namespace lw; - - -/*= A_ModBase ===============================================================*/ - -A_ModBase::~A_ModBase( ) noexcept -{ } - - -/*= A_NativeMod ==============================================================*/ - -OP_UserInterface A_NativeMod::getUserInterface( ) const noexcept -{ - return {}; -} diff --git a/src/Mods.cc b/src/Mods.cc deleted file mode 100644 index b24f927..0000000 --- a/src/Mods.cc +++ /dev/null @@ -1,2646 +0,0 @@ -/******************************************************************************/ -/* MODDING SYSTEM *************************************************************/ -/******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include - -using namespace lw; - - -/*= T_ModIdentifier ==========================================================*/ - -int T_ModIdentifier::compare( - T_ModIdentifier const& other ) const noexcept -{ - const int nc( name.compare( other.name ) ); - if ( nc != 0 ) { - return nc; - } - return T_Comparator< uint32_t >::compare( version , other.version ); -} - - -/*= MODULE CONFIGURATION DATA ================================================*/ - -namespace { - -struct T_ModConfig_ -{ - T_String name; - E_ModMode mode; - uint32_t version; - T_Optional< uint32_t > revision; - - explicit T_ModConfig_( - T_String name , - bool exclude ) noexcept; - T_ModConfig_( - T_String name , - uint32_t version ) noexcept; - T_ModConfig_( - T_String name , - uint32_t version , - uint32_t revision ) noexcept; -}; - -struct T_MMConfig_ -{ - T_ObjectTable< T_String , T_ModConfig_ > mods{ - []( T_ModConfig_ const& m ) -> T_String const& { - return m.name; - } , 64 - }; - T_KeyValueTable< T_String , int32_t > ui{ 64 }; -}; - -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_ModConfig_::T_ModConfig_( - T_String name , - const bool exclude ) noexcept - : name( std::move( name ) ) , - mode( exclude ? E_ModMode::EXCLUDE : E_ModMode::REQUIRE ) -{ } - -T_ModConfig_::T_ModConfig_( - T_String name , - const uint32_t version ) noexcept - : name( std::move( name ) ) , - mode( E_ModMode::VERSION ) , - version( version ) -{ } - -T_ModConfig_::T_ModConfig_( - T_String name , - const uint32_t version , - const uint32_t revision ) noexcept - : name( std::move( name ) ) , - mode( E_ModMode::VERSION ) , - version( version ) , - revision( revision ) -{ } - - -/*= MAIN CONFIGURATION PARSER ================================================*/ - -namespace { - -bool MMCModAuto_( - T_SRDParserData const& data ) noexcept -{ - auto const& input( *( data.input ) ); - auto& cfg( *data.currentData->value< SP_ModsManagerConfiguration >( ) ); - cfg.setAuto( input[ 1 ].stringValue( ) ); - return true; -} - -bool MMCModRequire_( - T_SRDParserData const& data ) noexcept -{ - auto const& input( *( data.input ) ); - auto& cfg( *data.currentData->value< SP_ModsManagerConfiguration >( ) ); - cfg.setRequired( input[ 1 ].stringValue( ) ); - return true; -} - -bool MMCModExclude_( - T_SRDParserData const& data ) noexcept -{ - auto const& input( *( data.input ) ); - auto& cfg( *data.currentData->value< SP_ModsManagerConfiguration >( ) ); - cfg.setExcluded( input[ 1 ].stringValue( ) ); - return true; -} - -bool MMCModVersion_( - T_SRDParserData const& data ) noexcept -{ - auto const& input( *( data.input ) ); - auto& cfg( *data.currentData->value< SP_ModsManagerConfiguration >( ) ); - const bool hasRevision( input.size( ) == 4 ); - - const uint32_t version( ([&](){ - const auto v( input[ 2 ].longValue( ) ); - if ( v < 0 || v > int64_t( UINT32_MAX ) ) { - data.errors.add( "invalid version number" , input[ 2 ] ); - return 0u; - } - return uint32_t( v ); - })( ) ); - - const uint32_t revision( ([&](){ - if ( !hasRevision ) { - return 0u; - } - const auto v( input[ 3 ].longValue( ) ); - if ( v < 0 || v > int64_t( UINT32_MAX ) ) { - data.errors.add( "invalid revision number" , input[ 2 ] ); - return 0u; - } - return uint32_t( v ); - })( ) ); - - if ( hasRevision ) { - cfg.setVersion( input[ 1 ].stringValue( ) , version , revision ); - } else { - cfg.setVersion( input[ 1 ].stringValue( ) , version ); - } - - return true; -} - -bool MMCSetUIPreference_( - T_SRDParserData const& data ) noexcept -{ - auto const& input( *( data.input ) ); - auto& cfg( *data.currentData->value< SP_ModsManagerConfiguration >( ) ); - const int32_t pref( input.size( ) == 3 ? input[ 2 ].longValue( ) : 0 ); - cfg.setUIPreference( input[ 1 ].stringValue( ) , pref ); - return true; -} - -bool MMCClearUIPreference_( - T_SRDParserData const& data ) noexcept -{ - auto& cfg( *data.currentData->value< SP_ModsManagerConfiguration >( ) ); - cfg.clearUIPreference( (*data.input)[ 1 ].stringValue( ) ); - return true; -} - -} // namespace - - -/*= T_ModsManagerConfiguration ===============================================*/ - -T_ModsManagerConfiguration::T_ModsManagerConfiguration( ) noexcept - : A_PrivateImplementation( new T_MMConfig_( ) ) -{ } - -T_ModsManagerConfiguration::T_ModsManagerConfiguration( - T_ModsManagerConfiguration&& other ) noexcept - : A_PrivateImplementation( std::move( other ) ) -{ } - -T_ModsManagerConfiguration& T_ModsManagerConfiguration::operator =( - T_ModsManagerConfiguration&& other ) noexcept -{ - A_PrivateImplementation::operator =( std::move( other ) ); - return *this; -} - -/*----------------------------------------------------------------------------*/ - -void T_ModsManagerConfiguration::setAuto( - T_String const& name ) noexcept -{ - p< T_MMConfig_ >( ).mods.remove( name ); -} - -void T_ModsManagerConfiguration::setRequired( - T_String const& name ) noexcept -{ - p< T_MMConfig_ >( ).mods.set( T_ModConfig_{ name , false } ); -} - -void T_ModsManagerConfiguration::setExcluded( - T_String const& name ) noexcept -{ - p< T_MMConfig_ >( ).mods.set( T_ModConfig_{ name , true } ); -} - -void T_ModsManagerConfiguration::setVersion( - T_String const& name , - const uint32_t version ) noexcept -{ - p< T_MMConfig_ >( ).mods.set( T_ModConfig_{ name , version } ); -} - -void T_ModsManagerConfiguration::setVersion( - T_String const& name , - const uint32_t version , - const uint32_t revision ) noexcept -{ - p< T_MMConfig_ >( ).mods.set( - T_ModConfig_{ name , version , revision } ); -} - -/*----------------------------------------------------------------------------*/ - -T_Array< T_String > T_ModsManagerConfiguration::configured( ) const noexcept -{ - return p< T_MMConfig_ >( ).mods.keys( ); -} - -E_ModMode T_ModsManagerConfiguration::modeFor( - T_String const& name ) const noexcept -{ - auto const* const mc( p< T_MMConfig_ >( ).mods.get( name ) ); - return mc ? mc->mode : E_ModMode::AUTO; -} - -uint32_t T_ModsManagerConfiguration::requiredVersion( - T_String const& name ) const noexcept -{ - auto const* const mc( p< T_MMConfig_ >( ).mods.get( name ) ); - assert( mc != nullptr && mc->mode == E_ModMode::VERSION ); - return mc->version; -} - -T_Optional< uint32_t > T_ModsManagerConfiguration::requiredRevision( - T_String const& name ) const noexcept -{ - auto const* const mc( p< T_MMConfig_ >( ).mods.get( name ) ); - assert( mc != nullptr && mc->mode == E_ModMode::VERSION ); - return mc->revision; -} - -/*----------------------------------------------------------------------------*/ - -void T_ModsManagerConfiguration::setUIPreference( - T_String const& name , - const int32_t weight ) noexcept -{ - p< T_MMConfig_ >( ).ui.set( name , weight ); -} - -void T_ModsManagerConfiguration::clearUIPreference( - T_String const& name ) noexcept -{ - p< T_MMConfig_ >( ).ui.remove( name ); -} - -T_Array< T_String > T_ModsManagerConfiguration::uiPreferences( ) const noexcept -{ - auto const& ui( p< T_MMConfig_ >( ).ui ); - T_Array< T_String > names( ui.keys( ) ); - names.sort( [&]( T_String const& a , T_String const& b ) { - return T_Comparator< int32_t >::compare( ui[ a ] , ui[ b ] ); - } ); - return names; -} - -int32_t T_ModsManagerConfiguration::uiPreference( - T_String const& name ) const noexcept -{ - int32_t const* const pref( p< T_MMConfig_ >( ).ui.get( name ) ); - if ( pref == nullptr ) { - return 0; - } - return *pref; -} - - -/*----------------------------------------------------------------------------*/ - -namespace { -/* Add a mod to the list if the specific name/version is not present. - * If it is present, replace the entry if the new record's revision - * number is higher than the one in the list. - */ -void addOrReplaceMod_( - T_Array< RPC_ModInfo >& list , - RPC_ModInfo const& mod ) -{ - auto const nMods( list.size( ) ); - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - auto const& record( *list[ i ] ); - if ( record.identifier != mod->identifier ) { - continue; - } - if ( record.revision < mod->revision ) { - list[ i ] = mod; - } - return; - } - list.add( mod ); -} -} // namespace - -T_Array< RPC_ModInfo > T_ModsManagerConfiguration::filterMods( - T_Array< RPC_ModInfo > const& mods ) const noexcept -{ - const auto nMods( mods.size( ) ); - T_Array< RPC_ModInfo > output{ std::max( 1u , nMods ) }; - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - auto const& mod( mods[ i ] ); - auto const& mn( mod->identifier.name ); - auto const m( modeFor( mn ) ); - - if ( m != E_ModMode::VERSION ) { - if ( m != E_ModMode::EXCLUDE ) { - addOrReplaceMod_( output , mod ); - } - continue; - } - - // Right version? - if ( mod->identifier.version != requiredVersion( mn ) ) { - continue; - } - auto const rv( requiredRevision( mn ) ); - if ( rv.present( ) && mod->revision != rv ) { - continue; - } - addOrReplaceMod_( output , mod ); - } - return output; -} - -T_Array< T_String > T_ModsManagerConfiguration::requiredMods( ) const noexcept -{ - auto const& pi( p< T_MMConfig_ >( ) ); - auto const nConfig( pi.mods.size( ) ); - uint32_t nRequired( 0 ); - for ( uint32_t i = 0 ; i < nConfig ; i ++ ) { - auto const m( pi.mods[ i ].mode ); - if ( m == E_ModMode::VERSION || m == E_ModMode::REQUIRE ) { - nRequired ++; - } - } - - T_Array< T_String > output{ std::max( 1u , nRequired ) }; - for ( uint32_t i = 0 ; i < nConfig ; i ++ ) { - auto const m( pi.mods[ i ].mode ); - if ( m == E_ModMode::VERSION || m == E_ModMode::REQUIRE ) { - output.add( pi.mods[ i ].name ); - if ( output.size( ) == nRequired ) { - break; - } - } - } - return output; -} - -/*----------------------------------------------------------------------------*/ - -T_ModsManagerConfiguration T_ModsManagerConfiguration::DefaultConfiguration( ) noexcept -{ - const T_String mGame( T_String::Pooled( "lw-game" ) ); - const T_String mConsoleUI( T_String::Pooled( "lw-ui-console" ) ); - const T_String mGLUI( T_String::Pooled( "lw-ui-gl" ) ); - - T_ModsManagerConfiguration config; - config.setRequired( mGame ); - config.setUIPreference( mConsoleUI , 100 ); - config.setUIPreference( mGLUI , 1000 ); - return config; -} - -/*----------------------------------------------------------------------------*/ - -T_SRDParserConfig T_ModsManagerConfiguration::GetParserConfig( ) -{ - using namespace lw::SRD; - T_SRDParserDefs defs( "default" ); - defs << OnStart( []( T_SRDParserData const& data ) -> bool { - *( data.currentData ) = NewShared< T_ModsManagerConfiguration >( ); - return true; - } ); - - defs.context( "default" ) - << ( Rule( ) << "auto" << Word( ) - << MMCModAuto_ ) - << ( Rule( ) << "require" << Word( ) - << MMCModRequire_ ) - << ( Rule( ) << "exclude" << Word( ) - << MMCModExclude_ ) - << ( Rule( ) << "version" << Word( ) << Int32( ) << Opt( Int32( ) ) - << MMCModVersion_ ) - << ( Rule( ) << "ui" << Word( ) << Opt( Int32( ) ) - << MMCSetUIPreference_ ) - << ( Rule( ) << "clear-ui" << Word( ) - << MMCClearUIPreference_ ) - ; - - return defs; -} - - -/*= T_MDData_ - Private data for T_ModsDependencies ==========================*/ - -using T_ModsList_ = T_Array< RPC_ModInfo >; - -namespace { - -struct T_UIMods_ -{ - T_String name; - T_ModsList_ mods{ 1 }; -}; - -struct T_MDData_ -{ - bool success = false; - bool ambiguous = false; - T_ModsList_ commonMods{ 1 }; - T_Array< T_UIMods_ > uiMods{ 1 }; -}; - -} // namespace - - -/*= MODS DEPENDENCIES RESOLUTION =============================================*/ - -namespace { - -using T_ModsTable_ = T_ObjectTable< T_ModIdentifier , RPC_ModInfo >; - -T_ModsTable_ makeModsTable_( - T_Array< RPC_ModInfo > const& mods ) noexcept -{ - const uint32_t nMods{ mods.size( ) }; - T_ModsTable_ mt{ - []( RPC_ModInfo mi ) -> T_ModIdentifier const& { - return mi->identifier; - } , nMods , 128 - }; - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - mt.add( mods[ i ] ); - } - return mt; -} - -/*----------------------------------------------------------------------------*/ - -using T_MinMaxVersions_ = std::pair< uint32_t , uint32_t >; -using T_ModVersions_ = T_KeyValueTable< T_String , T_MinMaxVersions_ >; - -T_ModVersions_ makeModVersions_( - T_Array< RPC_ModInfo > const& mods ) noexcept -{ - const uint32_t nMods( mods.size( ) ); - T_ModVersions_ versions{ nMods , 128 }; - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - auto const& mi( mods[ i ]->identifier ); - auto* previous( versions.get( mi.name ) ); - const auto v( mi.version ); - if ( previous == nullptr ) { - versions.add( mi.name , T_MinMaxVersions_( v , v ) ); - } else { - versions.update( mi.name , T_MinMaxVersions_( - std::min( previous->first , v ) , - std::max( previous->second , v ) ) ); - } - } - return versions; -} - -/*----------------------------------------------------------------------------*/ - -/* Structure used to represent graph nodes while building the - * dependency graph. - */ -struct T_MDRNode_ -{ - RPC_ModInfo mod; - bool valid; - T_Array< RPC_ModIdentifier > deps{ 16 }; - T_Array< T_String > uiDeps{ 4 }; - T_Optional< T_Array< RPC_ModIdentifier > > fullDeps; - T_Array< RPC_ModIdentifier > revDeps{ 16 }; - T_Optional< uint32_t > sgId; - - struct T_Dup {}; - - T_MDRNode_( - RPC_ModInfo mod , - bool valid , - T_Array< RPC_ModIdentifier >&& deps , - T_Array< T_String >&& uiDeps ) noexcept; - - T_MDRNode_( T_Dup , - T_MDRNode_ const& node ) noexcept; -}; - -/*----------------------------------------------------------------------------*/ - -T_MDRNode_::T_MDRNode_( - const RPC_ModInfo mod , - const bool valid , - T_Array< RPC_ModIdentifier >&& deps , - T_Array< T_String >&& uiDeps ) noexcept - : mod( mod ) , valid( valid ) , - deps( std::move( deps ) ) , uiDeps( std::move( uiDeps ) ) , - fullDeps( ) , revDeps( 16 ) , sgId( ) -{ } - - -T_MDRNode_::T_MDRNode_( - T_Dup , - T_MDRNode_ const& node ) noexcept - : mod( node.mod ) , valid( true ) , - deps( node.deps ) , fullDeps( node.fullDeps ) , - revDeps( 16 ) , sgId( ) -{ } - -/*----------------------------------------------------------------------------*/ - -struct T_MDRGraph_ -{ - T_Array< T_MDRNode_ > nodes; - T_String key; - float score; - uint32_t weight; - - explicit T_MDRGraph_( - const uint32_t nodesGrowth = 64 ) noexcept; - - /* Find a node based on a mod identifier. Returns INVALID_INDEX - * if no such node exists. - */ - uint32_t findNode( - T_ModIdentifier const& id ) const noexcept; - /* Remove invalid nodes from the graph */ - void removeBadNodes( ) noexcept; - /* Checks whether the graph is final (i.e. only has one - * version for each mod name). - */ - bool isFinal( ) const noexcept; - /* Generates the graph's "key", a sorted string of mod names. */ - void genKey( ) noexcept; - /* Compute the graph's score and weight */ - void computeScore( - T_ModVersions_ const& versions ) noexcept; -}; - -/*----------------------------------------------------------------------------*/ - -T_MDRGraph_::T_MDRGraph_( - const uint32_t nodesGrowth ) noexcept - : nodes( std::max( 1u , nodesGrowth ) ) -{ } - -uint32_t T_MDRGraph_::findNode( - T_ModIdentifier const& id ) const noexcept -{ - const uint32_t nn( nodes.size( ) ); - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - if ( nodes[ i ].mod->identifier == id ) { - return i; - } - } - return T_HashIndex::INVALID_INDEX; -} - -void T_MDRGraph_::removeBadNodes( ) noexcept -{ - uint32_t i = 0; - while ( i < nodes.size( ) ) { - if ( nodes[ i ].valid ) { - i ++; - } else { - nodes.removeSwap( i ); - } - } -} - -bool T_MDRGraph_::isFinal( ) const noexcept -{ - const uint32_t nn( nodes.size( ) ); - assert( nn > 0 ); - for ( uint32_t i = 0 ; i < nn - 1 ; i ++ ) { - T_String const& tnn( nodes[ i ].mod->identifier.name ); - for ( uint32_t j = i + 1 ; j < nn ; j ++ ) { - if ( tnn == nodes[ j ].mod->identifier.name ) { - return false; - } - } - } - return true; -} - -void T_MDRGraph_::genKey( ) noexcept -{ - const uint32_t nn( nodes.size( ) ); - assert( nn > 0 ); - - RPC_ModIdentifier ids[ nn ]; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - ids[ i ] = &( nodes[ i ].mod->identifier ); - } - Sort< RPC_ModIdentifier >( ids , nn , - []( RPC_ModIdentifier a , RPC_ModIdentifier b ) -> int { - return a->compare( *b ); - } ); - - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - if ( i != 0 ) { - sb << ' '; - } - sb << *ids[ i ]; - } - key = std::move( sb ); -} - -void T_MDRGraph_::computeScore( - T_ModVersions_ const& versions ) noexcept -{ - const uint32_t nn( nodes.size( ) ); - assert( nn > 0 ); - - float sum = 0; - weight = 0; - - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto const& mi( nodes[ i ].mod->identifier ); - auto const& mmv( *( versions.get( mi.name ) ) ); - const uint32_t nWeight( 1 + nodes[ i ].revDeps.size( ) ); - if ( mmv.first == mmv.second ) { - sum += nWeight; - } else { - sum += ( mi.version - mmv.first ) * nWeight - / float( mmv.second - mmv.first ); - } - weight += nWeight; - } - score = sum / float( weight ); -} - -/*----------------------------------------------------------------------------*/ - -int LoadOrderCmp_( RPC_ModInfo a , RPC_ModInfo b ) -{ - if ( a->modDeps.contains( b->identifier ) ) { - return 1; - } else if ( b->modDeps.contains( a->identifier ) ) { - return -1; - } - return a->identifier.compare( b->identifier ); -} - -/*----------------------------------------------------------------------------*/ - -struct T_MDResolver_ -{ - T_Logger& logger; - T_Array< T_String > const& required; - const T_ModsTable_ mods; - const T_ModVersions_ versions; - T_MDData_& output; - - T_MDResolver_( - T_Logger& logger , - T_Array< RPC_ModInfo > const& mods , - T_Array< T_String > const& required , - T_MDData_& output ) noexcept; - - /* Add a mod to the initial graph of mods and dependencies. - * All dependencies for the mod will be added. Will return - * true on success, or false if there is a cyclic dependency - * OR a dependency is missing OR a mod depends on more than - * one UI mod (this also prevents UI mods dependending on - * other UI mods). - */ - bool addModToInitialGraph( - T_MDRGraph_& graph , - T_ModIdentifier const& mod , - T_Array< T_ModIdentifier >& stack ) noexcept; - - /* Generate the list of transitive dependencies for a node */ - void generateFullDependencies( - T_MDRGraph_& graph , - const uint32_t nid ) noexcept; - /* Generate the list of transitive reverse dependencies for a node */ - void generateReverseDependencies( - T_MDRGraph_& graph , - const uint32_t nid ) noexcept; - /* Generate all transitive dependencies for a graph */ - void generateTransDepedencies( - T_MDRGraph_& graph ) noexcept; - - /* Build the initial graph from tha table of mods */ - T_MDRGraph_ buildInitialGraph( ) noexcept; - - /* Gather subgraph identifiers for a set of mods */ - void gatherSubgraphIds( - T_MDRGraph_& graph , - T_Array< RPC_ModIdentifier > const& deps , - T_Array< uint32_t >& ids ) noexcept; - /* Replace listed subgraph ids with another id */ - void replaceSubgraphIds( - T_Array< T_MDRNode_ >& nodes , - const uint32_t newId , - T_Array< uint32_t > const& replace ) noexcept; - /* Set the subgraph id for a set of nodes */ - void setSubgraphIds( - T_MDRGraph_& graph , - T_Array< RPC_ModIdentifier > const& ids , - const uint32_t sgId ) noexcept; - /* Find disjoint subgraphs in a graph, returning the array - * of subgraph identifiers. - */ - T_Array< uint32_t > findSubgraphs( - T_MDRGraph_& graph ) noexcept; - - /* Checks whether a subgraph contains all required mods - * (and at least one UI mod) - */ - bool checkSubgraph( - T_MDRGraph_ const& graph , - const uint32_t sgId ) noexcept; - /* Remove nodes that have the specified subgraph ID */ - void removeSubgraphNodes( - T_MDRGraph_& graph , - const uint32_t sgId ) noexcept; - /* Create a new graph based on a subgraph */ - T_MDRGraph_ subgraphToGraph( - T_MDRGraph_ const& graph , - const uint32_t sgId ) noexcept; - /* Create new graphs based on the specified subgraphs */ - T_Array< T_MDRGraph_ > subgraphsToGraphs( - T_MDRGraph_ const& graph , - T_Array< uint32_t> const& subgraphs ) noexcept; - - /* Generate a graph that will contain only one version of a mod. Once - * the graph is generated, it will be checked against the requirements - * and eliminated if it doesn't match. - */ - T_Optional< T_MDRGraph_ > reduceGraph( - T_MDRGraph_ const& source , - T_ModIdentifier const& wanted ) noexcept; - /* Generate reduced graphs from the first item in a list of graphs. - * The resulting graphs will be added to the list. They may or may not - * be final. - */ - void generateReducedGraphs( - T_Array< T_MDRGraph_ >& graphs ) noexcept; - /* Generate all final graphs from a list of graphs. */ - void generateFinalGraphs( - T_Array< T_MDRGraph_ >& graphs ) noexcept; - - /* Get the graph that will be used from the initial - * graph and the list of subgraphs. */ - T_Optional< T_MDRGraph_ > getGraph( - T_MDRGraph_ const& initialGraph , - T_Array< uint32_t > const& subgraphs ) noexcept; - - /* Copy a node and its dependencies from a graph to another. */ - void copyNodes( - T_MDRGraph_ const& source , - uint32_t node , - T_MDRGraph_& dest , - bool copyReverseDeps ) const noexcept; - - /* Split the final graph into UI-specific graphs */ - T_Array< T_MDRGraph_ > getUIGraphs( - T_MDRGraph_ const& graph ) noexcept; - /* Extract common mods from the various graphs */ - T_Array< RPC_ModInfo > findCommonMods( - T_MDRGraph_ const& graph , - T_Array< T_MDRGraph_ > const& uiGraphs ) noexcept; - /* Extract mods for a given UI */ - T_UIMods_ extractUIMods( - T_MDRGraph_ const& uiGraph , - T_ModsList_ const& commonMods ) noexcept; - /* Generate the list of UI mods */ - T_Array< T_UIMods_ > generateUILists( - T_Array< T_MDRGraph_ > const& uiGraphs , - T_ModsList_ const& commonMods ) noexcept; -}; - -/*----------------------------------------------------------------------------*/ - -T_MDResolver_::T_MDResolver_( - T_Logger& logger , - T_Array< RPC_ModInfo > const& mods , - T_Array< T_String > const& required , - T_MDData_& output ) noexcept - : logger( logger ) , required( required ) , - mods( makeModsTable_( mods ) ) , - versions( makeModVersions_( mods ) ) , - output( output ) -{ } - -/*----------------------------------------------------------------------------*/ - -bool T_MDResolver_::addModToInitialGraph( - T_MDRGraph_& graph , - T_ModIdentifier const& mod , - T_Array< T_ModIdentifier >& stack ) noexcept -{ - if ( stack.contains( mod ) ) { - logger.warning( ) << "Mod " << mod - << " is part of a cycle."; - return false; - } - - const uint32_t initialIndex( graph.findNode( mod ) ); - if ( initialIndex != T_HashIndex::INVALID_INDEX ) { - return graph.nodes[ initialIndex ].valid; - } - - RPC_ModInfo const* const miPtr( mods.get( mod ) ); - if ( miPtr == nullptr ) { - logger.warning( ) << "Mod " << mod - << " is missing."; - return false; - } - T_ModInfo const& mi( **miPtr ); - - bool valid( true ); - T_Array< RPC_ModIdentifier > deps{ 16 }; - T_Array< T_String > uiDeps{ 4 }; - if ( mi.isUserInterface( ) ) { - uiDeps.add( mi.identifier.name ); - } - - // Push to stack - const uint32_t stackIndex( stack.size( ) ); - stack.add( mod ); - - // Handle dependencies - const uint32_t nDeps( mi.modDeps.size( ) ); - for ( uint32_t i = 0 ; i < nDeps ; i ++ ) { - T_ModIdentifier const& di( mi.modDeps[ i ] ); - logger.trace( ) << "Checking " - << mod << " -> " << di - << " dependency"; - - const bool validDep( addModToInitialGraph( - graph , di , stack ) ); - assert( stack.size( ) == stackIndex + 1 ); - assert( stack[ stackIndex ] == mod ); - if ( !validDep ) { - valid = false; - continue; - } - - const uint32_t didx( graph.findNode( di ) ); - assert( didx != T_HashIndex::INVALID_INDEX ); - const RPC_ModIdentifier miPtr( &( graph.nodes[ didx ].mod->identifier ) ); - assert( !deps.contains( miPtr ) ); - deps.add( miPtr ); - - auto const& dr( graph.nodes[ didx ] ); - auto const nuid( dr.uiDeps.size( ) ); - for ( uint32_t j = 0 ; j < nuid ; j ++ ) { - if ( !uiDeps.contains( dr.uiDeps[ j ] ) ) { - uiDeps.add( dr.uiDeps[ j ] ); - } - } - } - if ( uiDeps.size( ) > 1 ) { - valid = false; - T_StringBuilder sb( "Mod " ); - sb << mod << " has more than 1 UI dependency:"; - for ( uint32_t i = 0 ; i < uiDeps.size( ) ; i ++ ) { - sb << ' ' << uiDeps[ i ]; - } - logger.warning( std::move( sb ) ); - } - - // Pop stack - stack.remove( stackIndex ); - - // Add the node - graph.nodes.addNew( *miPtr , valid , std::move( deps ) , - std::move( uiDeps ) ); - logger.trace( ) << "Added " - << ( valid ? "valid" : "invalid" ) - << " mod " << mod << " to the graph"; - return valid; -} - -/*----------------------------------------------------------------------------*/ - -void T_MDResolver_::generateFullDependencies( - T_MDRGraph_& graph , - const uint32_t nid ) noexcept -{ - auto& node( graph.nodes[ nid ] ); - if ( node.fullDeps.present( ) ) { - return; - } - - const uint32_t nd( node.deps.size( ) ); - T_Array< RPC_ModIdentifier > fd{ std::max( 1u , nd * 2 ) }; - for ( uint32_t i = 0 ; i < nd ; i ++ ) { - const auto did( node.deps[ i ] ); - if ( !fd.contains( did ) ) { - fd.add( did ); - } - - const auto didx( graph.findNode( *did ) ); - generateFullDependencies( graph , didx ); - - const auto& dep( graph.nodes[ didx ] ); - const auto& dfd( ( T_Array< RPC_ModIdentifier > const&) dep.fullDeps ); - const uint32_t nfd( dfd.size( ) ); - for ( uint32_t j = 0 ; j < nfd ; j ++ ) { - if ( !fd.contains( dfd[ j ] ) ) { - fd.add( dfd[ j ] ); - } - } - } - node.fullDeps = fd; - - if ( logger.hasLevel( E_LogLevel::TRACE ) ) { - if ( fd.size( ) == 0 ) { - logger.trace( ) << "No transitive dependencies for " - << node.mod->identifier; - } else { - T_StringBuilder sb( "Transitive dependencies for " ); - sb << node.mod->identifier << ':'; - const auto nfd( fd.size( ) ); - for ( uint32_t i = 0 ; i < nfd ; i ++ ) { - sb << ' ' << graph.nodes[ - graph.findNode( *fd[ i ] ) - ].mod->identifier; - } - logger.trace( std::move( sb ) ); - } - } -} - -void T_MDResolver_::generateReverseDependencies( - T_MDRGraph_& graph , - const uint32_t nid ) noexcept -{ - auto const& node( graph.nodes[ nid ] ); - const auto identifier{ &( node.mod->identifier ) }; - - auto const& dfd( ( T_Array< RPC_ModIdentifier > const&) node.fullDeps ); - const uint32_t nfd( dfd.size( ) ); - for ( uint32_t i = 0 ; i < nfd ; i ++ ) { - auto& tgt( graph.nodes[ graph.findNode( *dfd[ i ] ) ] ); - if ( !tgt.revDeps.contains( identifier ) ) { - tgt.revDeps.add( identifier ); - } - } -} - -void T_MDResolver_::generateTransDepedencies( - T_MDRGraph_& graph ) noexcept -{ - const uint32_t nn( graph.nodes.size( ) ); - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - generateFullDependencies( graph , i ); - } - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - generateReverseDependencies( graph , i ); - } - if ( !logger.hasLevel( E_LogLevel::TRACE ) ) { - return; - } - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto const& node( graph.nodes[ i ] ); - const auto& rd( node.revDeps ); - if ( rd.size( ) == 0 ) { - logger.trace( ) << "No transitive reverse dependencies for " - << node.mod->identifier; - } else { - T_StringBuilder sb( "Transitive reverse dependencies for " ); - sb << node.mod->identifier << ':'; - const auto nrd( rd.size( ) ); - for ( uint32_t i = 0 ; i < nrd ; i ++ ) { - sb << ' ' << *rd[ i ]; - } - logger.trace( std::move( sb ) ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -T_MDRGraph_ T_MDResolver_::buildInitialGraph( ) noexcept -{ - T_MDRGraph_ graph; - const uint32_t nMods( mods.size( ) ); - T_Array< T_ModIdentifier > stack; - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - addModToInitialGraph( graph , mods[ i ]->identifier , stack ); - assert( stack.size( ) == 0 ); - } - graph.removeBadNodes( ); - if ( graph.nodes.size( ) ) { - generateTransDepedencies( graph ); - } - return graph; -} - -/*----------------------------------------------------------------------------*/ - -void T_MDResolver_::gatherSubgraphIds( - T_MDRGraph_& graph , - T_Array< RPC_ModIdentifier > const& deps , - T_Array< uint32_t >& ids ) noexcept -{ - const uint32_t nd{ deps.size( ) }; - for ( uint32_t j = 0 ; j < nd ; j ++ ) { - auto const& dn( graph.nodes[ graph.findNode( *deps[ j ] ) ] ); - if ( dn.sgId.present( ) ) { - const uint32_t v( dn.sgId ); - if ( !ids.contains( v ) ) { - ids.add( v ); - } - } - } -} - -void T_MDResolver_::replaceSubgraphIds( - T_Array< T_MDRNode_ >& nodes , - const uint32_t newId , - T_Array< uint32_t > const& replace ) noexcept -{ - const uint32_t nn( nodes.size( ) ); - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto& node( nodes[ i ] ); - if ( !node.sgId.present( ) ) { - continue; - } - const uint32_t oldId( node.sgId ); - if ( replace.contains( oldId ) ) { - node.sgId = newId; - } - } -} - -void T_MDResolver_::setSubgraphIds( - T_MDRGraph_& graph , - T_Array< RPC_ModIdentifier > const& ids , - const uint32_t sgId ) noexcept -{ - const auto ni( ids.size( ) ); - for ( uint32_t i = 0 ; i < ni ; i ++ ) { - graph.nodes[ graph.findNode( *ids[ i ] ) ].sgId = sgId; - } -} - -/*----------------------------------------------------------------------------*/ - -T_Array< uint32_t > T_MDResolver_::findSubgraphs( - T_MDRGraph_& graph ) noexcept -{ - uint32_t nextId( 0 ); - T_Array< uint32_t > subgraphIds{ 16 }; - T_Array< uint32_t > curIds{ 16 }; - const auto nn( graph.nodes.size( ) ); - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto& node( graph.nodes[ i ] ); - if ( node.sgId.present( ) ) { - continue; - } - - // Find existing identifiers - curIds.clear( ); - gatherSubgraphIds( graph , node.fullDeps , curIds ); - gatherSubgraphIds( graph , node.revDeps , curIds ); - - // Get the nodes' new subgraph identifier - const uint32_t assign( ([&](){ - if ( curIds.size( ) != 0 ) { - const uint32_t temp( curIds[ 0 ] ); - curIds.removeSwap( 0 ); - return temp; - } else { - subgraphIds.add( nextId ); - return nextId ++; - } - })( ) ); - - // Replace other identifiers if there's more than 1 - if ( curIds.size( ) != 0 ) { - replaceSubgraphIds( graph.nodes , assign , curIds ); - for ( uint32_t j = 0 ; j < curIds.size( ) ; j ++ ) { - subgraphIds.removeSwap( subgraphIds.indexOf( curIds[ j ] ) ); - } - } - - // Assign new ID to node, deps and rdeps - node.sgId = assign; - setSubgraphIds( graph , node.fullDeps , assign ); - setSubgraphIds( graph , node.revDeps , assign ); - } - - // XXX assert all nodes have a subgraph ID - logger.trace( ) << "Generated " << subgraphIds.size( ) << " subgraphs"; - return subgraphIds; -} - -/*----------------------------------------------------------------------------*/ - -bool T_MDResolver_::checkSubgraph( - T_MDRGraph_ const& graph , - const uint32_t sgId ) noexcept -{ - bool rFound[ required.size( ) ]; - for ( uint32_t i = 0 ; i < required.size( ) ; i ++ ) { - rFound[ i ] = false; - } - - const uint32_t nn( graph.nodes.size( ) ); - bool hasUI( false ); - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto const& node( graph.nodes[ i ] ); - if ( node.sgId != sgId ) { - continue; - } - hasUI = hasUI || node.mod->isUserInterface( ); - - const auto rIdx( required.indexOf( node.mod->identifier.name ) ); - if ( rIdx != -1 ) { - rFound[ rIdx ] = true; - } - } - if ( !hasUI ) { - logger.trace( ) << "Subgraph #" << sgId - << ": no user interface"; - } - - bool ok( hasUI ); - for ( uint32_t i = 0 ; i < required.size( ) ; i ++ ) { - if ( !rFound[ i ] ) { - logger.trace( ) << "Subgraph #" << sgId - << ": missing required mod " << required[ i ]; - ok = false; - } - } - return ok; -} - -void T_MDResolver_::removeSubgraphNodes( - T_MDRGraph_& graph , - const uint32_t sgId ) noexcept -{ - uint32_t i = 0; - while ( i < graph.nodes.size( ) ) { - if ( graph.nodes[ i ].sgId == sgId ) { - graph.nodes.removeSwap( i ); - } else { - i ++; - } - } -} - -T_MDRGraph_ T_MDResolver_::subgraphToGraph( - T_MDRGraph_ const& graph , - const uint32_t sgId ) noexcept -{ - const uint32_t nn( graph.nodes.size( ) ); - const uint32_t ntn( ([&]() { - uint32_t ntn = 0; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - if ( graph.nodes[ i ].sgId == sgId ) { - ntn ++; - } - } - return ntn; - })( ) ); - assert( ntn != 0 ); - - T_MDRGraph_ ng{ ntn }; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto const& node( graph.nodes[ i ] ); - if ( node.sgId == sgId ) { - const uint32_t idx( ng.nodes.add( node ) ); - ng.nodes[ idx ].sgId.clear( ); - } - } - return ng; -} - -T_Array< T_MDRGraph_ > T_MDResolver_::subgraphsToGraphs( - T_MDRGraph_ const& graph , - T_Array< uint32_t> const& subgraphs ) noexcept -{ - const uint32_t nsg( subgraphs.size( ) ); - T_Array< T_MDRGraph_ > output{ std::max( 1u , 3 * nsg / 2 ) }; - for ( uint32_t i = 0 ; i < nsg ; i ++ ) { - output.add( subgraphToGraph( graph , subgraphs[ i ] ) ); - } - return output; -} - -/*----------------------------------------------------------------------------*/ - -T_Optional< T_MDRGraph_ > T_MDResolver_::reduceGraph( - T_MDRGraph_ const& source , - T_ModIdentifier const& wanted ) noexcept -{ - T_MDRGraph_ output( source ); - uint32_t i = 0; - while ( i < output.nodes.size( ) ) { - auto const& node( output.nodes[ i ] ); - auto const& nid( node.mod->identifier ); - if ( nid == wanted ) { - continue; - } - - bool remove; - if ( nid.name == wanted.name ) { - remove = true; - } else { - T_Array< RPC_ModIdentifier > const& fd( node.fullDeps ); - const uint32_t nfd( fd.size( ) ); - remove = false; - for ( uint32_t i = 0 ; i < nfd && !remove ; i ++ ) { - auto const& mi( *fd[ i ] ); - remove = mi.name == nid.name && mi.version != nid.version; - } - } - - if ( remove ) { - output.nodes.removeSwap( i ); - } else { - i ++; - } - } - - // Clear full reverse deps and regenerate them - const uint32_t nn( output.nodes.size( ) ); - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - output.nodes[ i ].revDeps.clear( ); - } - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - generateReverseDependencies( output , i ); - } - - // Now extract subgraphs and find the one that contains our target - findSubgraphs( output ); - auto const nid( output.findNode( wanted ) ); - uint32_t const sg( output.nodes[ nid ].sgId ); - if ( checkSubgraph( output , sg ) ) { - return subgraphToGraph( output , sg ); - } else { - return {}; - } -} - -void T_MDResolver_::generateReducedGraphs( - T_Array< T_MDRGraph_ >& graphs ) noexcept -{ - T_MDRGraph_ const& initial( graphs[ 0 ] ); - const uint32_t nn( initial.nodes.size( ) ); - - // Count the amount of different versions for each mod name - RPC_String names[ nn ]; - uint32_t counters[ nn ]; - uint32_t nNames = 0; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto const& nid( initial.nodes[ i ].mod->identifier ); - bool found( false ); - for ( uint32_t j = 0 ; j < nNames && !found ; j ++ ) { - if ( *names[ j ] == nid.name ) { - counters[ j ] ++; - found = true; - } - } - if ( !found ) { - names[ nNames ] = &nid.name; - counters[ nNames ] = 0; - nNames ++; - } - } - - // Generate graphs - for ( uint32_t i = 0 ; i < nNames ; i ++ ) { - if ( counters[ i ] == 0 ) { - continue; - } - for ( uint32_t j = 0 ; j < nn ; j ++ ) { - auto const& nid( initial.nodes[ j ].mod->identifier ); - if ( nid.name != *names[ i ] ) { - continue; - } - - auto gen( reduceGraph( initial , nid ) ); - if ( gen.present( ) ) { - logger.trace( ) - << "Generated new graph using " - << nid; - graphs.add( std::move( gen ) ); - } - } - } -} - -void T_MDResolver_::generateFinalGraphs( - T_Array< T_MDRGraph_ >& graphs ) noexcept -{ - T_Array< T_MDRGraph_ > output{ graphs.growth( ) }; - while ( graphs.size( ) != 0 ) { - T_MDRGraph_& initial( graphs[ 0 ] ); - if ( initial.isFinal( ) ) { - initial.genKey( ); - const uint32_t os( output.size( ) ); - bool found( false ); - for ( uint32_t i = 0 ; i < os ; i ++ ) { - if ( output[ i ].key == initial.key ) { - found = true; - break; - } - } - if ( !found ) { - logger.trace( ) - << "Adding final graph " - << initial.key; - output.add( std::move( initial ) ); - } - } else { - generateReducedGraphs( graphs ); - } - - graphs.removeSwap( 0 ); - } - logger.trace( ) << output.size( ) << " final graphs"; - graphs = output; -} - -/*----------------------------------------------------------------------------*/ - -T_Optional< T_MDRGraph_ > T_MDResolver_::getGraph( - T_MDRGraph_ const& initialGraph , - T_Array< uint32_t > const& subgraphs ) noexcept -{ - T_Array< T_MDRGraph_ > graphs{ subgraphsToGraphs( initialGraph , subgraphs ) }; - generateFinalGraphs( graphs ); - const uint32_t nGraphs( graphs.size( ) ); - if ( nGraphs == 0 ) { - logger.warning( ) << "No set of mods satisfies the configuration"; - return {}; - } - - const bool trace( logger.hasLevel( E_LogLevel::TRACE ) ); - uint32_t keepIndex = T_HashIndex::INVALID_INDEX , - maxWeight = 0 , - ambiguous = 0; - float maxScore = 0; - for ( uint32_t j = 0 ; j < nGraphs ; j ++ ) { - graphs[ j ].computeScore( versions ); - if ( trace ) { - logger.trace( ) << "Score/Weight ( " - << graphs[ j ].key << " ) = " - << graphs[ j ].score << " / " - << graphs[ j ].weight; - } - if ( graphs[ j ].score > maxScore ) { - keepIndex = j; - maxScore = graphs[ j ].score; - maxWeight = graphs[ j ].weight; - ambiguous = 0; - } else if ( graphs[ j ].score == maxScore - && graphs[ j ].weight > maxWeight ) { - keepIndex = j; - maxWeight = graphs[ j ].weight; - ambiguous = 0; - } else if ( graphs[ j ].score == maxScore - && graphs[ j ].weight == maxWeight ) { - ambiguous ++; - } - } - assert( keepIndex != T_HashIndex::INVALID_INDEX ); - output.ambiguous = ( ambiguous != 0 ); - if ( ambiguous ) { - logger.notice( ) << "Selected graph (" - << graphs[ keepIndex ].key - << ") but there were ambiguities."; - } else if ( trace ) { - logger.trace( ) << "Using graph (" - << graphs[ keepIndex ].key << ')'; - } - return std::move( graphs[ keepIndex ] ); -} - -/*----------------------------------------------------------------------------*/ - -void T_MDResolver_::copyNodes( - T_MDRGraph_ const& source , - const uint32_t nid , - T_MDRGraph_& dest , - const bool copyReverseDeps ) const noexcept -{ - auto const& nsrc( source.nodes[ nid ] ); - if ( dest.findNode( nsrc.mod->identifier ) != T_HashIndex::INVALID_INDEX ) { - return; - } - - dest.nodes.addNew( T_MDRNode_::T_Dup( ) , nsrc ); - - T_Array< RPC_ModIdentifier > const& deps( nsrc.fullDeps ); - const uint32_t nDeps( deps.size( ) ); - for ( uint32_t i = 0 ; i < nDeps ; i ++ ) { - copyNodes( source , source.findNode( *deps[ i ] ) , - dest , false ); - } - - if ( !copyReverseDeps ) { - return; - } - - const uint32_t nRevDeps( nsrc.revDeps.size( ) ); - for ( uint32_t i = 0 ; i < nRevDeps ; i ++ ) { - copyNodes( source , source.findNode( *nsrc.revDeps[ i ] ) , - dest , false ); - } -} - -T_Array< T_MDRGraph_ > T_MDResolver_::getUIGraphs( - T_MDRGraph_ const& graph ) noexcept -{ - const uint32_t nn( graph.nodes.size( ) ); - const uint32_t nui( ([&]() { - // How many UI mods? - uint32_t c = 0; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - if ( graph.nodes[ i ].mod->isUserInterface( ) ) { - c ++; - } - } - return c; - })( ) ); - logger.trace( ) << "About to generate " << nui << " per-UI graphs"; - T_Array< T_MDRGraph_ > output{ nui }; - for ( uint32_t i = 0 ; output.size( ) < nui ; i ++ ) { - assert( i < nn ); - auto const& node( graph.nodes[ i ] ); - if ( !node.mod->isUserInterface( ) ) { - continue; - } - - output.addNew( nn ); - auto& ng( output[ output.size( ) - 1 ] ); - copyNodes( graph , i , ng , true ); - - const uint32_t ngn( ng.nodes.size( ) ); - logger.trace( ) - << "Generated graph for UI mod " << *node.mod << " (" - << ngn << " nodes)"; - } - - return output; -} - -/*----------------------------------------------------------------------------*/ - -T_Array< RPC_ModInfo > T_MDResolver_::findCommonMods( - T_MDRGraph_ const& graph , - T_Array< T_MDRGraph_ > const& uiGraphs ) noexcept -{ - const uint32_t nn( graph.nodes.size( ) ); - const uint32_t nui( uiGraphs.size( ) ); - const uint32_t minMods( ([&](){ - uint32_t c = 0u; - for ( uint32_t i = 0 ; i < nui ; i ++ ) { - c = std::min( uiGraphs[ i ].nodes.size( ) , c ); - } - return std::max( 1u , c ); - })( ) ); - - RPC_ModIdentifier common[ minMods ]; - uint32_t nc = 0; - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - auto const& mgNode( graph.nodes[ i ] ); - if ( mgNode.uiDeps.size( ) != 0 ) { - continue; - } - - auto const& id( mgNode.mod->identifier ); - bool ok( true ); - for ( uint32_t j = 0 ; j < nui && ok ; j ++ ) { - ok = uiGraphs[ j ].findNode( id ) != T_HashIndex::INVALID_INDEX; - } - if ( ok ) { - common[ nc++ ] = &id; - } - } - - T_ModsList_ cml{ std::max( 1u , nc ) }; - for ( uint32_t i = 0 ; i < nc ; i ++ ) { - cml.add( *mods.get( *common[ i ] ) ); - } - cml.sort( LoadOrderCmp_ ); - - if ( logger.hasLevel( E_LogLevel::TRACE ) ) { - if ( nc != 0 ) { - T_StringBuilder sb( "Common mods:" ); - for ( uint32_t i = 0 ; i < nc ; i ++ ) { - sb << ' ' << *cml[ i ]; - } - logger.trace( std::move( sb ) ); - } else { - logger.trace( ) << "No common mods"; - } - } - - return cml; -} - -T_UIMods_ T_MDResolver_::extractUIMods( - T_MDRGraph_ const& uiGraph , - T_ModsList_ const& commonMods ) noexcept -{ - const uint32_t nn( uiGraph.nodes.size( ) ); - RPC_ModIdentifier ui( nullptr ); - RPC_ModInfo uiMods[ nn ]; - uint32_t nm = 0; - - for ( uint32_t i = 0 ; i < nn ; i ++ ) { - RPC_ModInfo nodeMod( uiGraph.nodes[ i ].mod ); - if ( commonMods.contains( nodeMod ) ) { - continue; - } - uiMods[ nm ++ ] = nodeMod; - if ( nodeMod->isUserInterface( ) ) { - assert( ui == nullptr ); - ui = &( nodeMod->identifier ); - } - } - assert( ui != nullptr ); - assert( nm > 0 ); - - T_ModsList_ uiml{ nm }; - for ( uint32_t i = 0 ; i < nm ; i ++ ) { - uiml.add( uiMods[ i ] ); - } - uiml.sort( LoadOrderCmp_ ); - - if ( logger.hasLevel( E_LogLevel::TRACE ) ) { - T_StringBuilder sb( "Mods for UI " ); - sb << ui->name << ':'; - for ( uint32_t i = 0 ; i < nm ; i ++ ) { - sb << ' ' << *uiml[ i ]; - } - logger.trace( std::move( sb ) ); - } - - return T_UIMods_{ ui->name , std::move( uiml ) }; -} - -T_Array< T_UIMods_ > T_MDResolver_::generateUILists( - T_Array< T_MDRGraph_ > const& uiGraphs , - T_ModsList_ const& commonMods ) noexcept -{ - const uint32_t nui( uiGraphs.size( ) ); - T_Array< T_UIMods_ > result{ nui }; - for ( uint32_t i = 0 ; i < nui ; i ++ ) { - result.add( extractUIMods( uiGraphs[ i ] , commonMods ) ); - } - return result; -} - -} // namespace - - -/*= T_ModsDependencies =======================================================*/ - -T_ModsDependencies::T_ModsDependencies( ) noexcept - : A_PrivateImplementation( new T_MDData_( ) ) -{ } - -T_ModsDependencies::T_ModsDependencies( - T_Logger& logger , - T_Array< RPC_ModInfo > const& mods , - T_ModsManagerConfiguration const& config ) noexcept - : A_PrivateImplementation( new T_MDData_( ) ) -{ - const bool trace( logger.hasLevel( E_LogLevel::TRACE ) ); - auto& pi( p< T_MDData_ >( ) ); - pi.success = false; - - const T_Array< RPC_ModInfo > matches{ config.filterMods( mods ) }; - if ( matches.size( ) == 0 ) { - logger.warning( "No mods left after applying filters" ); - return; - } - if ( trace ) { - T_StringBuilder sb( "Mods matching configuration:" ); - auto const nMods( mods.size( ) ); - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - sb << ' ' << *mods[ i ]; - } - logger.trace( std::move( sb ) ); - } - - const T_Array< T_String > required( config.requiredMods( ) ); - if ( trace ) { - if ( required.size( ) != 0 ) { - T_StringBuilder sb( "Required mods:" ); - for ( uint32_t i = 0 ; i < required.size( ) ; i ++ ) { - sb << ' ' << required[ i ]; - } - logger.trace( std::move( sb ) ); - } else { - logger.trace( ) << "No mod requirements"; - } - } - - logger.debug( ) << "Resolving mod dependencies"; - T_MDResolver_ resolver{ logger , matches , required , pi }; - T_MDRGraph_ initialGraph{ resolver.buildInitialGraph( ) }; - if ( initialGraph.nodes.size( ) == 0 ) { - logger.warning( ) << "No mods left after invalid dependencies removal"; - return; - } - logger.trace( ) << "Full graph: " << initialGraph.nodes.size( ) << " valid nodes"; - - T_Array< uint32_t > subgraphs( resolver.findSubgraphs( initialGraph ) ); - uint32_t i = 0; - while ( i < subgraphs.size( ) ) { - if ( resolver.checkSubgraph( initialGraph , subgraphs[ i ] ) ) { - i ++; - } else { - resolver.removeSubgraphNodes( initialGraph , subgraphs[ i ] ); - subgraphs.removeSwap( i ); - } - } - if ( subgraphs.size( ) == 0 ) { - logger.warning( ) << "No set of mods satisfies the configuration"; - return; - } - - auto graph( resolver.getGraph( initialGraph , subgraphs ) ); - if ( !graph.present( ) ) { - return; - } - auto uiGraphs( resolver.getUIGraphs( graph ) ); - pi.commonMods = resolver.findCommonMods( graph , uiGraphs ); - pi.uiMods = resolver.generateUILists( uiGraphs , pi.commonMods ); - pi.uiMods.sort( [&]( T_UIMods_ const& a , T_UIMods_ const& b ) -> int { - const auto pa( config.uiPreference( a.name ) ); - const auto pb( config.uiPreference( b.name ) ); - if ( pa == pb ) { - return a.name.compare( b.name ); - } - return -T_Comparator< int32_t >::compare( pa , pb ); - } ); - if ( trace ) { - T_StringBuilder sb( "User interfaces:" ); - for ( uint32_t i = 0 ; i < pi.uiMods.size( ) ; i ++ ) { - sb << ' ' << pi.uiMods[ i ].name; - } - logger.trace( std::move( sb ) ); - } - pi.success = true; -} - -// --------------------------------------------------------------------- - -T_ModsDependencies::T_ModsDependencies( - T_ModsDependencies const& other ) noexcept - : A_PrivateImplementation( new T_MDData_( other.p< T_MDData_ >( ) ) ) -{ } - -T_ModsDependencies& T_ModsDependencies::operator =( - T_ModsDependencies const& other ) noexcept -{ - p< T_MDData_ >( ) = other.p< T_MDData_ >( ); - return *this; -} - -T_ModsDependencies::T_ModsDependencies( - T_ModsDependencies&& other ) noexcept - : A_PrivateImplementation( std::move( other ) ) -{ } - -T_ModsDependencies& T_ModsDependencies::operator =( - T_ModsDependencies&& other ) noexcept -{ - A_PrivateImplementation::operator =( std::move( other ) ); - return *this; -} - -M_DECLARE_SWAP( T_ModsDependencies ) -{ - T_ModsDependencies temp( std::move( rhs ) ); - rhs = std::move( lhs ); - lhs = std::move( temp ); -} - -// --------------------------------------------------------------------- - -bool T_ModsDependencies::resolved( ) const -{ - return p< T_MDData_ >( ).success; -} - -bool T_ModsDependencies::ambiguous( ) const -{ - return p< T_MDData_ >( ).ambiguous; -} - -T_Array< T_String > T_ModsDependencies::userInterfaces( ) const -{ - auto const& pi( p< T_MDData_ >( ) ); - const auto nui( pi.uiMods.size( ) ); - T_Array< T_String > result{ nui }; - for ( uint32_t i = 0 ; i < nui ; i ++ ) { - result.add( pi.uiMods[ i ].name ); - } - return result; -} - -T_Array< RPC_ModInfo > const& T_ModsDependencies::commonMods( ) const -{ - return p< T_MDData_ >( ).commonMods; -} - -T_Array< RPC_ModInfo >::RPC T_ModsDependencies::forUserInterface( - T_String const& name ) const -{ - auto const& pi( p< T_MDData_ >( ) ); - const auto nui( pi.uiMods.size( ) ); - for ( uint32_t i = 0 ; i < nui ; i ++ ) { - auto const& uim( pi.uiMods[ i ] ); - if ( uim.name == name ) { - return &uim.mods; - } - } - return nullptr; -} - - -/*= DATA MOD DESCRIPTION FILE ================================================*/ - -namespace { -struct T_ModInfoFromDescr_ -{ - T_ModInfo modInfo; - bool hasVersion; - bool hasRevision; - bool hasLibVersion; -}; -using SP_MIFD = T_SharedPtr< T_ModInfoFromDescr_ >; - -bool DMDFInitialise_( T_SRDParserData const& d ) -{ - auto desc( NewShared< T_ModInfoFromDescr_ >( ) ); - desc->hasVersion = desc->hasRevision = desc->hasLibVersion = false; - desc->modInfo.type = E_ModType::DATA; - *( d.currentData ) = desc; - return true; -} - -bool DMDFSetName_( T_SRDParserData const& d ) -{ - auto const& tok( (*d.input)[ 1 ] ); - auto const& mi( d.currentData->value< SP_MIFD >( ) ); - if ( mi->modInfo.identifier.name ) { - d.errors.add( "duplicate module name" , tok ); - } else { - mi->modInfo.identifier.name = tok.stringValue( ); - } - return true; -} - -bool DMDFSetVersion_( T_SRDParserData const& d ) -{ - auto const& tok( (*d.input)[ 1 ] ); - auto const& mi( d.currentData->value< SP_MIFD >( ) ); - if ( mi->hasVersion ) { - d.errors.add( "duplicate version number" , tok ); - } - - const auto v( tok.longValue( ) ); - if ( v < 0 || v > UINT32_MAX ) { - d.errors.add( "invalid version number" , tok ); - } else { - mi->modInfo.identifier.version = tok.longValue( ); - } - mi->hasVersion = true; - return true; -} - -bool DMDFSetRevision_( T_SRDParserData const& d ) -{ - auto const& tok( (*d.input)[ 1 ] ); - auto const& mi( d.currentData->value< SP_MIFD >( ) ); - if ( mi->hasRevision ) { - d.errors.add( "duplicate revision number" , tok ); - } - - const auto v( tok.longValue( ) ); - if ( v < 0 || v > UINT32_MAX ) { - d.errors.add( "invalid revision number" , tok ); - } else { - mi->modInfo.revision = tok.longValue( ); - } - mi->hasRevision = true; - return true; -} - -bool DMDFSetLibVersion_( T_SRDParserData const& d ) -{ - auto const& tok( (*d.input)[ 1 ] ); - auto const& mi( d.currentData->value< SP_MIFD >( ) ); - if ( mi->hasLibVersion ) { - d.errors.add( "duplicate library version number" , tok ); - } - - const auto v( tok.longValue( ) ); - if ( v < 0 || v > UINT32_MAX ) { - d.errors.add( "invalid library version number" , tok ); - } else { - mi->modInfo.libVersion = tok.longValue( ); - } - mi->hasLibVersion = true; - return true; -} - -bool DMDFAddDependency_( T_SRDParserData const& d ) -{ - auto const& input( *d.input ); - auto const& mi( d.currentData->value< SP_MIFD >( ) ); - - bool add( true ); - auto const& name( input[ 1 ].stringValue( ) ); - auto& deps( mi->modInfo.modDeps ); - const auto nDeps( deps.size( ) ); - for ( uint32_t i = 0 ; i < nDeps ; i ++ ) { - if ( deps[ i ].name == name ) { - d.errors.add( "duplicate dependency" , input[ 1 ] ); - add = false; - break; - } - } - - const auto v( input[ 2 ].longValue( ) ); - if ( v < 0 || v > UINT32_MAX ) { - d.errors.add( "invalid version number" , input[ 2 ] ); - add = false; - } - - if ( add ) { - deps.add( T_ModIdentifier{ name , uint32_t( v ) } ); - } - return true; -} - -bool DMDFCheck_( T_SRDParserData const& d ) -{ - auto const& mi( d.currentData->value< SP_MIFD >( ) ); - if ( !mi->hasLibVersion ) { - d.errors.add( "no required library version" , T_SRDLocation( ) ); - } - if ( !mi->modInfo.identifier.name ) { - d.errors.add( "no name" , T_SRDLocation( ) ); - } - if ( !mi->hasVersion ) { - d.errors.add( "no version number" , T_SRDLocation( ) ); - } - if ( !mi->hasRevision ) { - d.errors.add( "no revision number" , T_SRDLocation( ) ); - } - *( d.currentData ) = NewShared< T_ModInfo >( std::move( mi->modInfo ) ); - return true; -} - -T_SRDParserConfig DMDFConfig_( ) -{ - using namespace lw::SRD; - - T_SRDParserDefs defs( "default" ); - defs << OnStart( DMDFInitialise_ ) << OnFinish( DMDFCheck_ ); - defs.context( "default" ) - << ( Rule( ) << "name" << Word( ) << DMDFSetName_ ) - << ( Rule( ) << "version" << Integer( ) << DMDFSetVersion_ ) - << ( Rule( ) << "revision" << Integer( ) << DMDFSetRevision_ ) - << ( Rule( ) << "library-version" << Integer( ) << DMDFSetLibVersion_ ) - << ( Rule( ) << "depends-on" << Word( ) << Integer( ) << DMDFAddDependency_ ) - ; - return T_SRDParserConfig( defs ); -} -} // namespace - - -/*= NATIVE MOD LOADING =======================================================*/ - -namespace { -class T_LoadedNativeMod_ : public A_NativeMod -{ - private: - T_Logger logger_; - T_String path_; - T_DynLib lib_; - OP_NativeMod mod_; - bool initialised_; - - public: - explicit T_LoadedNativeMod_( - T_Logger& logger , - T_String const& path ) noexcept; - ~T_LoadedNativeMod_( ) noexcept override; - - bool preinit( ) noexcept override; - bool init( F_UpdateInitProgress const& uip ) noexcept override; - void shutdown( ) noexcept override; - void postshutdown( ) noexcept override; - OP_UserInterface getUserInterface( ) const noexcept override; -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_LoadedNativeMod_::T_LoadedNativeMod_( - T_Logger& logger , - T_String const& path ) noexcept - : logger_( logger ) , path_( path ) , - lib_{ path } , mod_{} -{} - -T_LoadedNativeMod_::~T_LoadedNativeMod_( ) noexcept -{ - shutdown( ); - postshutdown( ); -} - -/*----------------------------------------------------------------------------*/ - -bool T_LoadedNativeMod_::preinit( ) noexcept -{ - assert( !mod_ ); - if ( !lib_.load( ) ) { - logger_.error( ) << "Native mod " << path_ - << " could not be loaded"; - return false; - } - - auto loader{ lib_.getFunction< void*( ) >( "LWMod_GetMod" ) }; - if ( !loader ) { - lib_.unload( ); - logger_.error( ) << "Cannot find mod entry point in " << path_; - return false; - } - - auto mod{ reinterpret_cast< RP_NativeMod >( loader( ) ) }; - if ( !mod ) { - lib_.unload( ); - logger_.error( ) << "Mod entry point returned NULL in " << path_; - return false; - } - - if ( !mod->preinit( ) ) { - delete mod; - lib_.unload( ); - return false; - } - - mod_ = OwnRawPointer( mod ); - initialised_ = false; - return true; -} - -/*----------------------------------------------------------------------------*/ - -bool T_LoadedNativeMod_::init( - F_UpdateInitProgress const& uip ) noexcept -{ - assert( mod_ && !initialised_ ); - initialised_ = mod_->init( uip ); - return initialised_; -} - -void T_LoadedNativeMod_::shutdown( ) noexcept -{ - if ( mod_ && initialised_ ) { - mod_->shutdown( ); - initialised_ = false; - } -} - -void T_LoadedNativeMod_::postshutdown( ) noexcept -{ - if ( mod_ && !initialised_ ) { - mod_->postshutdown( ); - mod_.clear( ); - lib_.unload( ); - } -} - -OP_UserInterface T_LoadedNativeMod_::getUserInterface( ) const noexcept -{ - assert( mod_ && !initialised_ ); - return mod_->getUserInterface( ); -} - - -/*= DATA MOD LOADING =========================================================*/ - -namespace { -class T_DataMod_ : public A_NativeMod -{ - private: - T_Logger logger_; - T_String path_; - T_RegisteredItem drv_; - - public: - explicit T_DataMod_( - T_Logger& logger , - T_String const& path ) noexcept; - ~T_DataMod_( ) noexcept override; - - bool preinit( ) noexcept override; - bool init( F_UpdateInitProgress const& ) noexcept override; - void shutdown( ) noexcept override; - void postshutdown( ) noexcept override; -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_DataMod_::T_DataMod_( - T_Logger& logger , - T_String const& path ) noexcept - : logger_( logger ) , path_( path ) , drv_{} -{ } - -T_DataMod_::~T_DataMod_( ) noexcept -{ - shutdown( ); - postshutdown( ); -} - -bool T_DataMod_::preinit( ) noexcept -{ - assert( !drv_ ); - drv_ = LW::vfs( ).addDriver( NewOwned< T_VFSDataFileDriver >( - NewOwned< T_File >( path_ , E_FileMode::READ_ONLY ) ) ); - if ( !drv_ ) { - logger_.error( ) << "Failed to initialise VFS data file driver from " - << T_String( path_ ); - return false; - } - return true; -} - -bool T_DataMod_::init( - F_UpdateInitProgress const& ) noexcept -{ - assert( drv_ ); - return true; -} - -void T_DataMod_::shutdown( ) noexcept -{ } - -void T_DataMod_::postshutdown( ) noexcept -{ - if ( drv_ ) { - drv_ = T_RegisteredItem( ); - } -} - - -/*= MODS MANAGER DATA ========================================================*/ - -namespace { - -struct T_MMData_ -{ - using T_ModIDs = T_Array< T_ModIdentifier >; - - const T_SRDParserConfig dmdfConfig_{ DMDFConfig_( ) }; - - T_ModsManagerConfiguration config_; - T_Logger logger{ "/core/mods" }; - - T_Array< OP_ModInfo > modsList{ 128 }; - T_ModsDependencies deps; - - T_Array< OP_NativeMod > mods; - T_Array< bool > states; - T_Array< RPC_ModInfo > loadedMods; - - // --------------------------------------------------------------------- - - T_MMData_( T_ModsManagerConfiguration&& config ) noexcept; - - // --------------------------------------------------------------------- - - /* Find all available mods. */ - bool scanForMods( ); - - /* Try to extract mod information from a file */ - OP_ModInfo getModInfo( - T_VFSPath const& path ) noexcept; - /* Try to extract mod information from a data file mod */ - OP_ModInfo getModInfoData( - T_VFSPath const& path , - OP_File& modFile ) noexcept; - /* Try to extract mod information from a native mod */ - OP_ModInfo getModInfoNative( - T_VFSPath const& path , - T_String const& fsPath ) noexcept; - - // --------------------------------------------------------------------- - - /* Set up the arrays for the mods' instances */ - void setupMods( ) noexcept; - - /* Load and pre-initialise a mod */ - bool loadMod( RPC_ModInfo mi ) noexcept; - /* "Rewind" the mod loader until only the specified amount of mods - * are left. This is meant for mods that have only been preinitialised. - */ - void rewindMods( uint32_t target ) noexcept; - - /* Load and preinitialise the UI mods, and try initialising the UI - * itself. - */ - OP_UserInterface loadUserInterface( - T_ModsList_ const& ml ) noexcept; -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_MMData_::T_MMData_( - T_ModsManagerConfiguration&& config ) noexcept - : config_( std::move( config ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -inline bool T_MMData_::scanForMods( ) -{ - const T_Array< T_VFSPath > paths( ([this]() { - T_Array< T_VFSPath > output; - LW::vfs( ).list( "/mods" , output ); - output.sort( []( T_VFSPath const& a , T_VFSPath const& b ) { - return T_String( a ).compare( T_String( b ) ); - } ); - return output; - })( ) ); - - T_Array< T_String > remove( 8 ); - const uint32_t nPaths( paths.size( ) ); - modsList.clear( ); - for ( uint32_t i = 0 ; i < nPaths ; i ++ ) { - const T_VFSPath path( "/mods" , paths[ i ] ); - logger.trace( ) << "Checking " << T_String( path ); - - if ( LW::vfs( ).typeOf( path ) != E_VFSEntryType::FILE ) { - logger.trace( ) << T_String( path ) << " is not a file"; - continue; - } - - OP_ModInfo info( getModInfo( path ) ); - if ( !info ) { - continue; - } - if ( remove.contains( info->identifier.name ) ) { - continue; - } - - const auto nMods( modsList.size( ) ); - bool badMod( false ); - for ( uint32_t j = 0 ; j < nMods ; j ++ ) { - auto const& mod( *modsList[ j ] ); - badMod = mod.identifier == info->identifier - && mod.revision == info->revision; - if ( badMod ) { - logger.notice( ) << T_String( path ) << " and " - << T_String( mod.path ) - << " contain the same mod (" - << *info << ')'; - break; - } - - badMod = mod.identifier.name == info->identifier.name - && mod.isUserInterface( ) != info->isUserInterface( ); - if ( badMod ) { - remove.add( mod.identifier.name ); - auto const& uiMod( mod.isUserInterface( ) ? mod : *info ); - auto const& otherMod( mod.isUserInterface( ) ? *info : mod ); - logger.notice( ) << "Mod " << uiMod - << " is an UI mod, " << otherMod - << " isn't; " << uiMod.identifier.name - << " will be discarded."; - break; - } - } - if ( !badMod ) { - logger.info( ) << "Found mod " << *info - << " in " << T_String( path ); - modsList.add( std::move( info ) ); - } - } - - // Remove "bad" mods - auto const nRemove( remove.size( ) ); - for ( uint32_t i = 0 ; i < nRemove ; i ++ ) { - auto const& name( remove[ i ] ); - for ( uint32_t j = 0 ; j < modsList.size( ) ; j ++ ) { - if ( modsList[ i ]->identifier.name == name ) { - modsList.removeSwap( j ); - j --; - } - } - } - - return modsList.size( ) > 0; -} - -/*----------------------------------------------------------------------------*/ - -OP_ModInfo T_MMData_::getModInfo( - T_VFSPath const& path ) noexcept -{ - OP_File modFile( LW::vfs( ).file( path ) ); - if ( !modFile ) { - logger.error( ) << "couldn't access " << T_String( path ); - return OP_ModInfo( ); - } - const T_String fsPath( modFile->path( ) ); - - OP_ModInfo result( getModInfoData( path , modFile ) ); - if ( !result ) { - modFile.clear( ); - result = getModInfoNative( path , fsPath ); - } - if ( result ) { - result->path = fsPath; - } - return result; -} - -OP_ModInfo T_MMData_::getModInfoData( - T_VFSPath const& path , - OP_File& modFile ) noexcept -{ - const T_String p( path ); - auto drv( NewOwned< T_VFSDataFileDriver >( std::move( modFile ) ) ); - if ( !drv->init( ) ) { - logger.trace( ) << p << " is not a data file"; - return OP_ModInfo( ); - } - - OP_ModInfo modInfo; - OP_InputStream stream( drv->read( "/mods/modinfo.srd" ) ); - if ( stream ) { - T_SRDParser parser( dmdfConfig_ ); - T_SRDTextReader reader( parser ); - try { - reader.read( T_String( "modinfo.srd" ) , *stream ); - modInfo = NewOwned< T_ModInfo >( std::move( - *parser.getData< SP_ModInfo >( ) ) ); - } catch ( X_StreamError const& e ) { - logger.error( ) << "Error while reading modinfo.srd from " - << p << ": " << e.what( ); - } catch ( X_SRDErrors const& e ) { - logger.error( ) << "Couldn't read mod description from " << p; - e.log( logger ); - } - } else { - logger.error( ) << "No module description in " << p; - } - drv->shutdown( ); - - if ( modInfo ) { - if ( modInfo->libVersion != LibVersion( ) ) { - logger.info( ) << p << " is incompatible with this version"; - modInfo.clear( ); - } else { - logger.trace( ) << p << " is a data mod"; - } - } - return modInfo; -} - -OP_ModInfo T_MMData_::getModInfoNative( - T_VFSPath const& path , - T_String const& fsPath ) noexcept -{ - const T_String p( path ); - - T_DynLib lib( fsPath ); - if ( !lib.load( ) ) { - logger.trace( ) << p << " is not a library; loader error: " - << lib.lastError( ); - return OP_ModInfo( ); - } - - uint32_t const* const pLibVersion( lib.getPointer< uint32_t >( - "LWMod_RequiredLibVersion" ) ); - if ( pLibVersion == nullptr ) { - logger.trace( ) << p << " is not a LW mod"; - return OP_ModInfo( ); - } - if ( *pLibVersion != LibVersion( ) ) { - logger.info( ) << p << " is incompatible with this version"; - return OP_ModInfo( ); - } - - char const* const pModName( lib.getPointer< char >( "LWMod_Name" ) ); - auto const* const pModVersion( lib.getPointer< uint32_t >( "LWMod_Version" ) ); - auto const* const pModRevision( lib.getPointer< uint32_t >( "LWMod_Revision" ) ); - bool const* const pIsUI( lib.getPointer< bool >( "LWMod_IsUserInterface" ) ); - if ( pModName == nullptr || pModVersion == nullptr - || pModRevision == nullptr || pIsUI == nullptr ) { - logger.error( ) << p << " is missing some mod information"; - return OP_ModInfo( ); - } - if ( lib.getRawSymbol( "LWMod_GetMod" ) == nullptr ) { - logger.error( ) << p << " does not have an entry point"; - return OP_ModInfo( ); - } - - auto mi( NewOwned< T_ModInfo >( ) ); - mi->type = *pIsUI ? E_ModType::UI : E_ModType::NATIVE; - mi->identifier.name = T_String( pModName ); - mi->identifier.version = *pModVersion; - mi->revision = *pModRevision; - mi->libVersion = *pLibVersion; - - auto const* const pDepCount( lib.getPointer< uint32_t >( "LWMod_DepCount" ) ); - if ( pDepCount && *pDepCount ) { - logger.trace( ) << p << " contains " << *pDepCount << " dependency record(s)"; - char const* const* const pDepNames( - lib.getPointer< char const* const >( "LWMod_DepNames" ) ); - auto const* const pDepVersions( - lib.getPointer< uint32_t >( "LWMod_DepVersions" ) ); - if ( pDepNames == nullptr || pDepVersions == nullptr ) { - logger.notice( ) << p << " has missing dependency fields"; - return OP_ModInfo( ); - } - for ( uint32_t i = 0 ; i < *pDepCount ; i ++ ) { - T_String dName( pDepNames[ i ] ); - for ( uint32_t j = 0 ; j < i ; j ++ ) { - if ( mi->modDeps[ j ].name == dName ) { - logger.notice( ) << p - << " contains duplicate dependency on " - << dName; - return {}; - } - } - mi->modDeps.add( T_ModIdentifier{ - std::move( dName ) , - pDepVersions[ i ] } ); - } - } - logger.trace( ) << p << " is a valid " - << ( mi->type == E_ModType::NATIVE ? "native" : "user interface" ) - << " mod"; - return mi; -} - -/*----------------------------------------------------------------------------*/ - -void T_MMData_::setupMods( ) noexcept -{ - assert( mods.size( ) == 0 ); - - const uint32_t nCommon( deps.commonMods( ).size( ) ); - const auto uiSets( deps.userInterfaces( ) ); - const auto nui( uiSets.size( ) ); - uint32_t nUIMods = 0; - for ( uint32_t i = 0 ; i < nui ; i ++ ) { - auto mptr( deps.forUserInterface( uiSets[ i ] ) ); - assert( mptr != nullptr ); - nUIMods = std::max( nUIMods , mptr->size( ) ); - } - - const uint32_t nMods( nCommon + nUIMods ); - assert( nMods > 0 ); - mods = T_Array< OP_NativeMod >{ nMods }; - states = T_Array< bool >{ nMods }; - loadedMods = T_Array< RPC_ModInfo >{ nMods }; -} - -bool T_MMData_::loadMod( - const RPC_ModInfo mi ) noexcept -{ - logger.trace( ) << "Loading mod " << *mi; - OP_NativeMod mod( ([&]() -> OP_NativeMod { - if ( mi->type == E_ModType::DATA ) { - return NewOwned< T_DataMod_ >( - logger , mi->path ); - } - return NewOwned< T_LoadedNativeMod_ >( - logger , mi->path ); - })( ) ); - - if ( mod->preinit( ) ) { - mods.add( std::move( mod ) ); - states.add( false ); - loadedMods.add( mi ); - logger.info( ) << "Loaded mod " << *mi; - return true; - } else { - return false; - } -} - -void T_MMData_::rewindMods( - const uint32_t target ) noexcept -{ - assert( target <= mods.size( ) ); - if ( target == mods.size( ) ) { - return; - } - - if ( logger.hasLevel( E_LogLevel::DEBUG ) ) { - T_StringBuilder sb( "Unloading the previous " ); - const uint32_t nUnload( mods.size( ) - target ); - if ( nUnload > 1 ) { - sb << nUnload << " mods"; - } else { - sb << "mod"; - } - logger.debug( std::move( sb ) ); - } - - uint32_t left; - while ( ( left = mods.size( ) ) != target ) { - const uint32_t index( left - 1 ); - auto& mod( mods[ index ] ); - assert( !states[ index ] ); - mod->postshutdown( ); - mods.remove( index ); - states.remove( index ); - loadedMods.remove( index ); - } -} - -/*----------------------------------------------------------------------------*/ - -OP_UserInterface T_MMData_::loadUserInterface( - T_ModsList_ const& ml ) noexcept -{ - const uint32_t rewindTarget( mods.size( ) ); - const uint32_t nMods( mods.size( ) ); - - T_Optional< uint32_t > uiModIndex{ }; - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - if ( loadMod( ml[ i ] ) ) { - if ( ml[ i ]->isUserInterface( ) ) { - assert( !uiModIndex.present( ) ); - uiModIndex = mods.size( ) - 1; - } - continue; - } - rewindMods( rewindTarget ); - return {}; - } - assert( uiModIndex.present( ) ); - - OP_UserInterface uiInst( mods[ uiModIndex ]->getUserInterface( ) ); - if ( uiInst && uiInst->preinit( ) ) { - return std::move( uiInst ); - } - uiInst.clear( ); - rewindMods( rewindTarget ); - return {}; -} - - -/*= T_ModsManager ============================================================*/ - -T_ModsManager::T_ModsManager( - T_ModsManagerConfiguration&& config ) noexcept - : A_PrivateImplementation( new T_MMData_( std::move( config ) ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -bool T_ModsManager::scanForMods( ) -{ - return p< T_MMData_ >( ).scanForMods( ); -} - -T_Array< RPC_ModInfo > T_ModsManager::availableMods( ) const noexcept -{ - auto const& ml( p< T_MMData_ >( ).modsList ); - const auto nm( ml.size( ) ); - T_Array< RPC_ModInfo > result{ std::max( 1u , nm ) }; - for ( uint32_t i = 0 ; i < nm ; i ++ ) { - result.add( ml[ i ].get( ) ); - } - return result; -} - -bool T_ModsManager::resolveDependencies( ) noexcept -{ - auto& pi( p< T_MMData_ >( ) ); - pi.deps = T_ModsDependencies{ pi.logger , availableMods( ) , pi.config_ }; - return pi.deps.resolved( ); -} - -/*----------------------------------------------------------------------------*/ - -bool T_ModsManager::preinitCommon( ) noexcept -{ - auto& pi( p< T_MMData_ >( ) ); - pi.setupMods( ); - - T_ModsList_ const& common( pi.deps.commonMods( ) ); - const uint32_t ncm( common.size( ) ); - for ( uint32_t i = 0 ; i < ncm ; i ++ ) { - if ( !pi.loadMod( common[ i ] ) ) { - pi.rewindMods( 0 ); - return false; - } - } - return true; -} - -OP_UserInterface T_ModsManager::preinitUIMods( - T_String const& ui ) noexcept -{ - auto& pi( p< T_MMData_ >( ) ); - auto mods( pi.deps.forUserInterface( ui ) ); - if ( mods == nullptr ) { - pi.logger.error( ) << "No mods for UI '" << ui << '\''; - return {}; - } - return pi.loadUserInterface( *mods ); -} - -OP_UserInterface T_ModsManager::preinitUIMods( ) noexcept -{ - auto& pi( p< T_MMData_ >( ) ); - auto uis( pi.deps.userInterfaces( ) ); - const auto nui( uis.size( ) ); - for ( uint32_t i = 0 ; i < nui ; i ++ ) { - pi.logger.debug( ) - << "Attempting to load & initialise UI " - << uis[ i ]; - - auto mods( pi.deps.forUserInterface( uis[ i ] ) ); - assert( mods != nullptr ); - - OP_UserInterface ui( pi.loadUserInterface( *mods ) ); - if ( ui ) { - return ui; - } - pi.logger.notice( ) - << "Could not initialise UI " << uis[ i ]; - } - pi.logger.error( ) << "All attempts at initialising an UI failed"; - return {}; -} - -/*----------------------------------------------------------------------------*/ - -uint32_t T_ModsManager::modsCount( ) const noexcept -{ - return p< T_MMData_ >( ).loadedMods.size( ); -} - -bool T_ModsManager::initialise( - F_CreateInitUpdater const& ciuf ) noexcept -{ - auto& pi( p< T_MMData_ >( ) ); - - const auto nMods( pi.loadedMods.size( ) ); - pi.logger.trace( ) << "Initialising mods"; - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - auto& mod( pi.mods[ i ] ); - auto desc( pi.loadedMods[ i ] ); - auto& state( pi.states[ i ] ); - if ( state ) { - pi.logger.error( ) << "Mod " << *desc - << " is already initialised"; - shutdown( ); - return false; - } - pi.logger.trace( ) << "Initialising mod " << *desc; - if ( !mod->init( ciuf( desc ) ) ) { - pi.logger.error( ) << "Mod " << *desc - << " failed to initialise"; - shutdown( ); - return false; - } - state = true; - } - return true; -} - -/*----------------------------------------------------------------------------*/ - -void T_ModsManager::shutdown( ) noexcept -{ - auto& pi( p< T_MMData_ >( ) ); - - pi.logger.trace( ) << "Mods shutdown"; - const uint32_t nMods( pi.mods.size( ) ); - for ( uint32_t i = 0 ; i < nMods ; i ++ ) { - const uint32_t index( nMods - ( i + 1 ) ); - auto& mod( pi.mods[ index ] ); - auto& state( pi.states[ index ] ); - if ( state ) { - pi.logger.trace( ) << "Shutting down mod " - << *( pi.loadedMods[ index ] ); - mod->shutdown( ); - state = false; - } else { - pi.logger.debug( ) << "Mod " - << *( pi.loadedMods[ index ] ) - << " is not initialised, skipping shutdown"; - } - } -} - -void T_ModsManager::unload( ) noexcept -{ - p< T_MMData_ >( ).rewindMods( 0 ); -} diff --git a/src/SRDBinary.cc b/src/SRDBinary.cc index 26d723c..f3fd4f1 100644 --- a/src/SRDBinary.cc +++ b/src/SRDBinary.cc @@ -2,8 +2,8 @@ /* SRD PARSER AND PREPROCESSOR - BINARY FORM **********************************/ /******************************************************************************/ -#include -using namespace lw; +#include +using namespace ebcl; /*= MAGIC NUMBERS, VERSIONS AND TAGS =========================================*/ @@ -36,7 +36,7 @@ enum class E_V1Tag_ : uint8_t { } // namespace -namespace lw { +namespace ebcl { // Writer for version numbers template< > diff --git a/src/SRDData.cc b/src/SRDData.cc index af665b0..bfbab1e 100644 --- a/src/SRDData.cc +++ b/src/SRDData.cc @@ -2,10 +2,9 @@ /* SRD PARSER AND PREPROCESSOR - DATA REPRESENTATION **************************/ /******************************************************************************/ -#include -#include -#include -using namespace lw; +#include +#include +using namespace ebcl; /*= T_SRDLocation ============================================================*/ @@ -58,7 +57,7 @@ T_SRDLocation::T_SRDLocation( swap( *this , other ); } -namespace lw { +namespace ebcl { M_DECLARE_SWAP( T_SRDLocation ) { using std::swap; @@ -149,34 +148,10 @@ char const* X_SRDErrors::what( ) const noexcept return "SRD read/parse errors"; } -#ifndef LW_MINLIB -void X_SRDErrors::log( T_Logger& logger ) const -{ - const auto nErrors( errors.size( ) ); - for ( size_t i = 0 ; i < nErrors ; i ++ ) { - auto sb( logger.error( ) ); - auto const& e( errors[ i ] ); - auto const& l( e.location( ) ); - - if ( l.unknown( ) ) { - sb << "unknown location"; - } else { - sb << l.source( ); - if ( l.binary( ) ) { - sb << ", b" << l.byte( ); - } else { - sb << ", l" << l.line( ) << ", c" << l.character( ); - } - } - sb << ": " << e.error( ); - } -} -#endif // LW_MINLIB - /*= T_SRDToken =============================================================*/ -T_StringBuilder& lw::operator<< ( T_StringBuilder& sb , E_SRDTokenType tt ) +T_StringBuilder& ebcl::operator<< ( T_StringBuilder& sb , E_SRDTokenType tt ) { static char const* const C_TOKEN_TYPES_[] = { "(...)" , @@ -425,7 +400,7 @@ T_SRDToken& T_SRDToken::operator= ( T_SRDToken const& other ) /*----------------------------------------------------------------------------*/ -void lw::swap( T_SRDToken& lhs , T_SRDToken& rhs ) noexcept +void ebcl::swap( T_SRDToken& lhs , T_SRDToken& rhs ) noexcept { using std::swap; swap( lhs.type_ , rhs.type_ ); diff --git a/src/SRDDefinitions.cc b/src/SRDDefinitions.cc index 06c60cd..0fdf15d 100644 --- a/src/SRDDefinitions.cc +++ b/src/SRDDefinitions.cc @@ -3,8 +3,8 @@ /******************************************************************************/ -#include -using namespace lw; +#include +using namespace ebcl; /*= T_SRDEnum ================================================================*/ @@ -52,7 +52,7 @@ uint32_t T_SRDEnum::operator[] ( char const* word ) const /*= T_SRDInputItem ===========================================================*/ -void lw::swap( T_SRDInputItem& lhs , T_SRDInputItem& rhs ) noexcept +void ebcl::swap( T_SRDInputItem& lhs , T_SRDInputItem& rhs ) noexcept { using std::swap; swap( lhs.type_ , rhs.type_ ); @@ -80,7 +80,7 @@ T_SRDInputItem& T_SRDInputItem::operator<< ( T_SRDInputItem item ) /*----------------------------------------------------------------------------*/ -T_StringBuilder& lw::operator<< ( T_StringBuilder& sb , T_SRDInputItem const& item ) +T_StringBuilder& ebcl::operator<< ( T_StringBuilder& sb , T_SRDInputItem const& item ) { switch ( item.type( ) ) { @@ -166,7 +166,7 @@ T_SRDInputRule& T_SRDInputRule::operator<< ( T_SRDInputItem item ) return *this; } -T_StringBuilder& lw::operator<< ( T_StringBuilder& sb , T_SRDInputRule const& item ) +T_StringBuilder& ebcl::operator<< ( T_StringBuilder& sb , T_SRDInputRule const& item ) { auto const& seq( item.rule( ) ); sb << '('; diff --git a/src/SRDIO.cc b/src/SRDIO.cc index 61460a4..e78c604 100644 --- a/src/SRDIO.cc +++ b/src/SRDIO.cc @@ -3,8 +3,8 @@ /******************************************************************************/ -#include -using namespace lw; +#include +using namespace ebcl; /*= X_SRDWriterError =========================================================*/ @@ -36,7 +36,7 @@ A_SRDWriter& A_SRDWriter::putToken( T_SRDToken const& token ) case E_SRDTokenType::LIST: startList( ); putList( token.list( ) ); - + // fall through case E_SRDTokenType::END: return endList( ); diff --git a/src/SRDPPCommands.cc b/src/SRDPPCommands.cc deleted file mode 100644 index 827afd5..0000000 --- a/src/SRDPPCommands.cc +++ /dev/null @@ -1,2518 +0,0 @@ -/******************************************************************************/ -/* SRD - PREPROCESSOR COMMANDS ************************************************/ -/******************************************************************************/ - -#include -#include -#include -#include -#include -#include -using namespace lw; - - -/*= BUILTIN COMMANDS INITIALIZER =============================================*/ - -#define M_ADDCMD_( NAME , ARGS... ) \ - add< T_SRDPPCMD_ ## NAME >( ARGS ) - -void T_SRDPreprocessorConfig::addBuiltinCommands( ) noexcept -{ - M_ADDCMD_( Add ); - M_ADDCMD_( And ); - M_ADDCMD_( Bless ); - M_ADDCMD_( Break ); - M_ADDCMD_( BwAnd ); - M_ADDCMD_( BwNot ); - M_ADDCMD_( BwOr ); - M_ADDCMD_( BwXor ); - M_ADDCMD_( Call ); - M_ADDCMD_( CastString ); - M_ADDCMD_( CastWord ); - M_ADDCMD_( CastInt ); - M_ADDCMD_( CastLong ); - M_ADDCMD_( CastBestInt ); - M_ADDCMD_( CastReal ); - M_ADDCMD_( CastVar ); - M_ADDCMD_( CastList ); - M_ADDCMD_( ClearScope ); - M_ADDCMD_( Cmp ); - M_ADDCMD_( CmpEq ); - M_ADDCMD_( CmpNe ); - M_ADDCMD_( CmpLt ); - M_ADDCMD_( CmpGt ); - M_ADDCMD_( CmpLe ); - M_ADDCMD_( CmpGe ); - M_ADDCMD_( Concat ); - M_ADDCMD_( Div ); - M_ADDCMD_( EndsWith ); - M_ADDCMD_( Eval ); - M_ADDCMD_( Error ); - M_ADDCMD_( FromSource ); - M_ADDCMD_( FromSRB ); - M_ADDCMD_( Get ); - M_ADDCMD_( If ); - M_ADDCMD_( Ignore ); - M_ADDCMD_( IsBlessed ); - M_ADDCMD_( IsMacro ); - M_ADDCMD_( IsSet ); - M_ADDCMD_( Length ); - M_ADDCMD_( ListMacros ); - M_ADDCMD_( ListVariables ); - M_ADDCMD_( Mod ); - M_ADDCMD_( Mul ); - M_ADDCMD_( Neg ); - M_ADDCMD_( Not ); - M_ADDCMD_( Or ); - M_ADDCMD_( Output ); - M_ADDCMD_( Raw ); - M_ADDCMD_( Rethrow ); - M_ADDCMD_( Scope ); - M_ADDCMD_( Set ); - M_ADDCMD_( SetMacro ); - M_ADDCMD_( StartsWith ); - M_ADDCMD_( StrFind ); - M_ADDCMD_( StrSplit ); - M_ADDCMD_( Sub ); - M_ADDCMD_( Substr ); - M_ADDCMD_( ToSource ); - M_ADDCMD_( Try ); - M_ADDCMD_( TypeOf ); - M_ADDCMD_( Unset ); - M_ADDCMD_( UnsetMacro ); - M_ADDCMD_( Unwrap ); - M_ADDCMD_( Xor ); -} - -void T_SRDPreprocessorConfig::addVFSCommands( - T_VFS& vfs ) noexcept -{ - M_ADDCMD_( VFSList , vfs ); - M_ADDCMD_( VFSLoad , vfs ); - M_ADDCMD_( VFSType , vfs ); -} - - -/*= HELPER FOR MATH COMMANDS =================================================*/ - -typedef std::function< int64_t( int64_t , int64_t ) > F_LongOp_; -typedef std::function< double ( double , double ) > F_RealOp_; - -namespace { - -void DoMathOp_( T_SRDPreprocessorState& state , F_LongOp_ longOp , F_RealOp_ realOp , bool nonZero = false ) -{ - auto& input( state.output( ) ); - auto& output( state.data( ).top( ).output( ) ); - auto const& location( *state.initialLocation( ) ); - - const uint32_t nInputs( input.size( ) ); - if ( nInputs < 2 ) { - state.data( ).addError( location , "not enough arguments" ); - if ( nInputs == 0 ) { - T_SRDToken r( T_SRDToken::Integer( 0 ) ); - r.location( location ); - output.add( std::move( r ) ); - return; - } - } - - const E_SRDTokenType type( input[ 0 ].type( ) ); - if ( type != E_SRDTokenType::INT && type != E_SRDTokenType::LONG && type != E_SRDTokenType::FLOAT ) { - state.data( ).addError( input[ 0 ] , "numeric argument expected" ); - } - - bool hadReal( type == E_SRDTokenType::FLOAT ); - int64_t rl( input[ 0 ].longValue( ) ); - double rr( input[ 0 ].floatValue( ) ); - for ( uint32_t i = 1 ; i < nInputs ; i ++ ) { - auto& tok( input[ i ] ); - const auto tt( tok.type( ) ); - if ( tt != E_SRDTokenType::INT && tt != E_SRDTokenType::LONG && - tt != E_SRDTokenType::FLOAT ) { - state.data( ).addError( tok , "numeric argument expected" ); - continue; - } - if ( tok.floatValue( ) == 0 && nonZero ) { - state.data( ).addError( tok , "non-zero argument expected" ); - continue; - } - hadReal = hadReal || tt == E_SRDTokenType::FLOAT; - if ( !hadReal ) { - rl = longOp( rl , tok.longValue( ) ); - } - rr = realOp( rr , tok.floatValue( ) ); - } - - T_SRDToken result( hadReal ? T_SRDToken::Float( rr ) : T_SRDToken::AutoInteger( rl ) ); - result.location( location ); - output.add( std::move( result ) ); -} - -void DoLogicOp_( T_SRDPreprocessorState& state , F_LongOp_ op ) -{ - auto& input( state.output( ) ); - auto& output( state.data( ).top( ).output( ) ); - auto const& location( *state.initialLocation( ) ); - - const uint32_t nInputs( input.size( ) ); - if ( nInputs < 2 ) { - state.data( ).addError( location , "not enough arguments" ); - if ( nInputs == 0 ) { - T_SRDToken r( T_SRDToken::Integer( 0 ) ); - r.location( location ); - output.add( std::move( r ) ); - return; - } - } - if ( !input[ 0 ].isInteger( ) ) { - state.data( ).addError( input[ 0 ] , "integer argument expected" ); - } - - int64_t rl( input[ 0 ].longValue( ) ); - for ( uint32_t i = 1 ; i < nInputs ; i ++ ) { - auto& tok( input[ i ] ); - if ( !tok.isInteger( ) ) { - state.data( ).addError( tok , "integer argument expected" ); - continue; - } - rl = op( rl , tok.longValue( ) ); - } - - T_SRDToken result( T_SRDToken::AutoInteger( rl ) ); - result.location( location ); - output.add( std::move( result ) ); -} - -} - - -/*= HELPER FOR COMPARISONS ===================================================*/ - -namespace { - -bool CompareInput_( T_SRDPreprocessorState & state , int & result ) -{ - auto& data( state.data( ) ); - auto& input( state.output( ) ); - auto& loc( *state.initialLocation( ) ); - - if ( input.size( ) < 2 ) { - data.addError( loc , "not enough arguments" ); - return false; - } - if ( input.size( ) > 2 ) { - data.addError( loc , "too many arguments" ); - return false; - } - - result = input[ 0 ].compare( input[ 1 ] ); - return true; -} - -} - - -/*= COMMANDS =================================================================*/ - -M_SRDPP_COMMAND_EXEC( Add ) -{ - DoMathOp_( state , - []( auto a , auto b ) { - return a + b; - } , - []( auto a , auto b ) { - return a + b; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( And ) -{ - DoLogicOp_( state , - []( auto a , auto b ) { - return ( a && b ) ? 1 : 0; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Bless ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - const auto n( input.size( ) ); - if ( n == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto const& ntok( input[ i ] ); - if ( ntok.type( ) != E_SRDTokenType::WORD ) { - data.addError( ntok , "word expected" ); - continue; - } - - auto const& vn( ntok.stringValue( ) ); - auto& s( data.scopes( ) ); - if ( s.isBlessed( vn ) ) { - continue; - } - - RPC_SRDList var( s.get( false , vn ) ); - if ( var == nullptr ) { - data.addError( ntok , "unknown variable" ); - continue; - } - - if ( T_SRDPreprocessor::isValidFunction( *var ) ) { - s.bless( vn ); - } else { - data.addError( ntok , "variable does not contain a valid function" ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Break ) -{ - if ( state.output( ).size( ) ) { - state.data().addError( *state.initialLocation( ) , "too many arguments" ); - } - state.data( ).interrupt( T_SRDPreprocessorState::C_CALL ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( BwAnd ) -{ - DoLogicOp_( state , - []( auto a , auto b ) { - return a & b; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( BwNot ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - bool useLong( false ); - int64_t iv( 0 ); - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) != 1 ) { - data.addError( loc , "too many arguments" ); - } else if ( !input[ 0 ].isInteger( ) ) { - data.addError( input[ 0 ] , "integer argument expected" ); - } else { - iv = ~input[ 0 ].longValue( ); - useLong = ( input[ 0 ].type( ) == E_SRDTokenType::LONG ); - if ( !useLong ) { - iv = iv & 0xffffffff; - } - } - - T_SRDToken output( useLong ? T_SRDToken::Long( iv ) : T_SRDToken::Integer( iv ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( BwOr ) -{ - DoLogicOp_( state , - []( auto a , auto b ) { - return a | b; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( BwXor ) -{ - DoLogicOp_( state , - []( auto a , auto b ) { - return a ^ b; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Call ) -{ - auto& data( state.data( ) ); - auto& input( state.output( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) < 1 ) { - data.addError( loc , "not enough arguments" ); - return; - } - - auto& func( input[ 0 ] ); - if ( !T_SRDPreprocessor::isValidFunction( func ) ) { - data.addError( func , "invalid function" ); - return; - } - - auto const& argsTok( func.list( )[ 0 ] ); - auto const& args( argsTok.list( ) ); - const bool hasOptArgs( args.size( ) > 0 - && args[ args.size( ) - 1 ].type( ) == E_SRDTokenType::LIST ); - const uint32_t reqArgs( args.size( ) - ( hasOptArgs ? 1 : 0 ) ); - const auto nValues( input.size( ) - 1 ); - if ( nValues < reqArgs ) { - data.addError( loc , "not enough function arguments" ); - return; - } - if ( nValues > reqArgs && !hasOptArgs ) { - data.addError( loc , "too many function arguments" ); - return; - } - - data.scopes( ).setupCallScope( args , input , 1 ); - data.push( T_SRDPreprocessorState::C_CALL , - NewShared< T_SRDList >( func.list( ).moveRange( 1 ) ) , - data.top( ).outputPointer( ) , - []( T_SRDPreprocessorState& ns ) { - ns.data( ).scopes( ).exit( ); - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastString ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - T_String outString; - switch ( token.type( ) ) { - - case E_SRDTokenType::STRING: - output.add( std::move( token ) ); - continue; - - case E_SRDTokenType::WORD: - outString = token.stringValue( ); - break; - - case E_SRDTokenType::INT: - case E_SRDTokenType::LONG: - { - T_StringBuilder sb; - sb << token.longValue( ); - outString = std::move( sb ); - break; - } - - case E_SRDTokenType::FLOAT: - { - T_StringBuilder sb; - sb << token.floatValue( ); - outString = std::move( sb ); - break; - } - - case E_SRDTokenType::VAR: - { - T_StringBuilder sb; - sb << '$' << token.stringValue( ); - outString = std::move( sb ); - break; - } - - case E_SRDTokenType::BINARY: - { - auto const& buffer( token.binary( ) ); - outString = T_String( (char const*) buffer.data( ) , - buffer.bytes( ) ); - if ( !outString.valid( ) ) { - outString = T_String( ); - data.addError( token , "invalid UTF-8 data" ); - } - break; - } - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - - T_SRDToken otok( T_SRDToken::String( std::move( outString ) ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastWord ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - T_String outString; - switch ( token.type( ) ) { - - case E_SRDTokenType::STRING: - outString = token.stringValue( ); - if ( !T_SRDToken::IsWord( outString ) ) { - data.addError( token , "invalid word" ); - continue; - } - break; - - case E_SRDTokenType::WORD: - output.add( std::move( token ) ); - continue; - - case E_SRDTokenType::VAR: - outString = token.stringValue( ); - break; - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - - T_SRDToken otok( T_SRDToken::Word( std::move( outString ) ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastInt ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - int64_t value; - switch ( token.type( ) ) { - - case E_SRDTokenType::INT: - output.add( std::move( token ) ); - continue; - - case E_SRDTokenType::STRING: - { - bool ok; - value = token.stringValue( ).toInteger( &ok ); - if ( !ok ) { - data.addError( token , "invalid integer value" ); - continue; - } - break; - } - - case E_SRDTokenType::LONG: - value = token.longValue( ); - break; - - case E_SRDTokenType::FLOAT: - value = token.floatValue( ); - break; - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - if ( value < INT32_MIN || value > INT32_MAX ) { - data.addError( token , "value out of range" ); - continue; - } - - T_SRDToken otok( T_SRDToken::Integer( value ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastLong ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - int64_t value; - switch ( token.type( ) ) { - - case E_SRDTokenType::LONG: - output.add( std::move( token ) ); - continue; - - case E_SRDTokenType::STRING: - { - bool ok; - value = token.stringValue( ).toInteger( &ok ); - if ( !ok ) { - data.addError( token , "invalid integer value" ); - continue; - } - break; - } - - case E_SRDTokenType::INT: - value = token.longValue( ); - break; - - case E_SRDTokenType::FLOAT: - value = token.floatValue( ); - break; - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - - T_SRDToken otok( T_SRDToken::Long( value ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastBestInt ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - int64_t value; - switch ( token.type( ) ) { - - case E_SRDTokenType::INT: - output.add( std::move( token ) ); - continue; - - case E_SRDTokenType::STRING: - { - bool ok; - value = token.stringValue( ).toInteger( &ok ); - if ( !ok ) { - data.addError( token , "invalid integer value" ); - continue; - } - break; - } - - case E_SRDTokenType::LONG: - value = token.longValue( ); - break; - - case E_SRDTokenType::FLOAT: - value = token.floatValue( ); - break; - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - - T_SRDToken otok( T_SRDToken::AutoInteger( value ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastReal ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - double value; - switch ( token.type( ) ) { - - case E_SRDTokenType::FLOAT: - output.add( std::move( token ) ); - continue; - - case E_SRDTokenType::STRING: - { - bool ok; - value = token.stringValue( ).toDouble( &ok ); - if ( !ok ) { - data.addError( token , "invalid real value" ); - continue; - } - break; - } - - case E_SRDTokenType::INT: - case E_SRDTokenType::LONG: - value = token.longValue( ); - break; - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - - T_SRDToken otok( T_SRDToken::Float( value ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastVar ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - - T_String outString; - switch ( token.type( ) ) { - - case E_SRDTokenType::STRING: - outString = token.stringValue( ); - if ( outString[ 0 ] == '$' ) { - outString = outString.substr( 1 ); - } - if ( !T_SRDToken::IsWord( outString ) || outString[ 0 ] == '-' ) { - data.addError( token , "invalid variable name" ); - continue; - } - break; - - case E_SRDTokenType::WORD: - outString = token.stringValue( ); - if ( outString[ 0 ] == '-' ) { - data.addError( token , "invalid variable name" ); - continue; - } - break; - - case E_SRDTokenType::VAR: - output.add( std::move( token ) ); - continue; - - default: - data.addError( token , "unsupported type conversion" ); - continue; - - } - - T_SRDToken otok( T_SRDToken::Variable( std::move( outString ) ) ); - otok.copyLocationOf( token ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( CastList ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - const auto size( input.size( ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto& token( input[ i ] ); - switch ( token.type( ) ) { - - case E_SRDTokenType::STRING: - case E_SRDTokenType::WORD: - { - T_StringIterator it( token.stringValue( ) ); - T_StringBuilder sb; - while ( !it.atEnd( ) ) { - T_Character c( it ); - it.next( ); - sb << c; - T_SRDToken ctok( T_SRDToken::String( sb ) ); - ctok.copyLocationOf( token ); - output.add( std::move( ctok ) ); - sb.clear( ); - } - break; - } - - case E_SRDTokenType::BINARY: - { - auto const& buffer( token.binary( ) ); - const auto bs( buffer.size( ) ); - for ( auto i = 0u ; i < bs ; i ++ ) { - T_SRDToken vtok( T_SRDToken::Integer( buffer[ i ] ) ); - vtok.copyLocationOf( token ); - output.add( std::move( vtok ) ); - } - break; - } - - case E_SRDTokenType::LIST: - { - auto const& l( token.list( ) ); - const auto ls( l.size( ) ); - for ( auto i = 0u ; i < ls ; i ++ ) { - output.add( std::move( l[ i ] ) ); - } - break; - } - - default: - output.add( std::move( token ) ); - continue; - - } - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( ClearScope ) -{ - if ( state.output( ).size( ) != 0 ) { - auto& data( state.data( ) ); - data.scopes( ).enter( ); - data.scopes( ).clear( ); - data.push( T_SRDPreprocessorState::C_INNER , - state.outputPointer( ) , data.top( ).outputPointer( ) , - []( T_SRDPreprocessorState & ns ) { - ns.data( ).scopes( ).exit( ); - } ); - } else { - state.data( ).scopes( ).clear( ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Cmp ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( success ? result : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -M_SRDPP_COMMAND_EXEC( CmpEq ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( ( success && result == 0 ) ? 1 : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -M_SRDPP_COMMAND_EXEC( CmpNe ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( ( success && result != 0 ) ? 1 : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -M_SRDPP_COMMAND_EXEC( CmpLt ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( ( success && result < 0 ) ? 1 : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -M_SRDPP_COMMAND_EXEC( CmpGt ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( ( success && result > 0 ) ? 1 : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -M_SRDPP_COMMAND_EXEC( CmpLe ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( ( success && result <= 0 ) ? 1 : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -M_SRDPP_COMMAND_EXEC( CmpGe ) -{ - int result; - bool success( CompareInput_( state , result ) ); - T_SRDToken token( T_SRDToken::Integer( ( success && result >= 0 ) ? 1 : 0 ) ); - token.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( token ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Concat ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - auto const& loc( *state.initialLocation( ) ); - - const auto size( input.size( ) ); - if ( size == 0 ) { - data.addError( loc , "not enough arguments" ); - T_SRDToken otok( T_SRDToken::String( T_String( "" ) ) ); - otok.location( loc ); - output.add( std::move( otok ) ); - return; - } - - // Find out whether this is a string concatenation or a binary - // concatenation. - uint32_t binLength = 0; - bool isBinary = true; - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto const& token( input[ i ] ); - if ( token.type( ) != E_SRDTokenType::BINARY ) { - isBinary = false; - break; - } - binLength += token.binary( ).size( ); - } - - // Binary concat - if ( isBinary ) { - auto ob( NewShared< T_Buffer< uint8_t > >( binLength ) ); - binLength = 0; - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto const& bin( input[ i ].binary( ) ); - memcpy( ob->data( ) + binLength , - bin.data( ) , bin.size( ) ); - binLength += bin.size( ); - } - T_SRDToken otok( T_SRDToken::Binary( ob ) ); - otok.location( loc ); - output.add( std::move( otok ) ); - return; - } - - // String concat - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < size ; i ++ ) { - auto const& token( input[ i ] ); - if ( !( token.isText( ) || token.isNumeric( ) ) ) { - data.addError( token , "expected text or numeric argument" ); - continue; - } - - switch ( token.type( ) ) { - - case E_SRDTokenType::STRING: - case E_SRDTokenType::WORD: - sb << token.stringValue( ); - continue; - - case E_SRDTokenType::INT: - case E_SRDTokenType::LONG: - sb << token.longValue( ); - break; - - case E_SRDTokenType::FLOAT: - sb << token.floatValue( ); - break; - - default: - assert( 0 && "we shouldn't be here" ); - continue; - - } - } - - T_SRDToken otok( T_SRDToken::String( std::move( sb ) ) ); - otok.location( loc ); - output.add( std::move( otok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Div ) -{ - DoMathOp_( state , - []( auto a , auto b ) { - return a / b; - } , - []( auto a , auto b ) { - return a / b; - } , true ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( EndsWith ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - uint32_t value = 0; - if ( input.size( ) < 2 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) > 2 ) { - data.addError( loc , "too many arguments" ); - } else { - if ( input[ 0 ].isText( ) && input[ 1 ].isText( ) ) { - value = input[ 1 ].stringValue( ).endsWith( - input[ 0 ].stringValue( ) ); - } else if ( input[ 0 ].type( ) == E_SRDTokenType::BINARY - && input[ 1 ].type( ) == E_SRDTokenType::BINARY ) { - auto const& needle( input[ 0 ].binary( ) ); - auto const& haystack( input[ 1 ].binary( ) ); - auto const nsz( needle.size( ) ); - auto const hsz( haystack.size( ) ); - value = ( nsz <= hsz - && !( nsz && memcmp( needle.data( ) , - haystack.data( ) + hsz - nsz , - nsz ) ) ); - } else { - data.addError( loc , "invalid arguments" ); - } - } - - auto tok( T_SRDToken::Integer( value ) ); - tok.location( loc ); - data.top( ).output( ).add( std::move( tok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Eval ) -{ - if ( state.output( ).size( ) == 0 ) { - return; - } - auto& data( state.data( ) ); -// data.push( T_SRDPreprocessorState::C_CALL , state.outputPointer( ) , -// data.top( ).outputPointer( ) ); - auto& input( state.output( ) ); - const auto is( input.size( ) ); - if ( is ) { - const SP_SRDLocation evalLocation( state.createChainedLocation( ) ); - SP_SRDList updated( NewShared< T_SRDList >( is ) ); - for ( size_t i = 0 ; i < is ; i ++ ) { - T_SRDToken token( std::move( input[ i ] ) ); - - auto& loc( token.location( ) ); - SP_SRDLocation el( ( i == is - 1 ) - ? evalLocation - : NewShared< T_SRDLocation >( *evalLocation ) ); - if ( loc.isChained( ) ) { - auto const& lc( loc.chaining( ) ); - el->chain( lc.circumstances , lc.location ); - } - loc.chain( E_SRDLocationChaining::EVALUATED , el ); - - updated->add( std::move( token ) ); - } - - data.push( T_SRDPreprocessorState::C_UNSPECIFIED , updated , - data.top( ).outputPointer( ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Error ) -{ - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - auto& input( state.output( ) ); - const auto nTokens( input.size( ) ); - if ( nTokens == 0 ) { - data.addError( loc , "user error" ); - } else { - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < nTokens ; i ++ ) { - if ( i > 0 ) { - sb << ' '; - } - auto& tok( input[ i ] ); - switch( tok.type( ) ) { - - case E_SRDTokenType::VAR: - sb << '$'; - case E_SRDTokenType::STRING: - case E_SRDTokenType::WORD: - sb << tok.stringValue( ); - break; - - case E_SRDTokenType::INT: - case E_SRDTokenType::LONG: - sb << tok.longValue( ); - break; - - case E_SRDTokenType::FLOAT: - sb << tok.floatValue( ); - break; - - case E_SRDTokenType::LIST: - tok.generateFullText( ); - sb << tok.fullText( ); - break; - - default: - sb << "(INTERNAL ERROR)"; - break; - } - } - data.addError( loc , sb ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( FromSource ) -{ - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - auto& input( state.output( ) ); - const auto is( input.size( ) ); - if ( is == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( is > 2 ) { - data.addError( loc , "too many arguments" ); - } - - if ( input[ 0 ].type( ) != E_SRDTokenType::STRING ) { - data.addError( input[ 0 ] , "string expected" ); - return; - } - if ( is == 2 && !input[ 1 ].isText( ) ) { - data.addError( input[ 1 ] , "word or string expected" ); - } - - const T_String inputName( ( is == 2 && input[ 1 ].isText( ) ) - ? input[ 1 ].stringValue( ) - : T_String::Pooled( "(-from-source)" ) ); - T_SRDErrors& errors( data.errorContext( ) ); - - T_SRDMemoryTarget tgt( true ); - T_SRDLexer lexer( inputName , errors , tgt ); - tgt.start( errors ); - - T_StringIterator it( input[ 0 ].stringValue( ) ); - while ( !it.atEnd( ) ) { - lexer.processCharacter( it ); - it.next( ); - } - lexer.processEnd( ); - - auto const& generated( tgt.list( ) ); - auto& output( data.top( ).output( ) ); - const auto gs( generated.size( ) ); - const SP_SRDLocation gloc( state.createChainedLocation( ) ); - for ( size_t i = 0 ; i < gs ; i ++ ) { - T_SRDToken t( generated[ i ] ); - t.location( ).chain( E_SRDLocationChaining::GENERATED , gloc ); - output.add( std::move( t ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( FromSRB ) -{ - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - auto& input( state.output( ) ); - const auto is( input.size( ) ); - if ( is == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( is > 2 ) { - data.addError( loc , "too many arguments" ); - } - - if ( input[ 0 ].type( ) != E_SRDTokenType::BINARY ) { - data.addError( input[ 0 ] , "binary array expected" ); - return; - } - if ( is == 2 && !input[ 1 ].isText( ) ) { - data.addError( input[ 1 ] , "word or string expected" ); - } - - const T_String inputName( ( is == 2 && input[ 1 ].isText( ) ) - ? input[ 1 ].stringValue( ) - : T_String::Pooled( "(-from-srb)" ) ); - T_SRDErrors& errors( data.errorContext( ) ); - - T_SRDMemoryTarget tgt( true ); - T_SRDBinaryReader reader( tgt ); - T_MemoryInputStream istream( input[ 0 ].binary( ) ); - try { - reader.read( inputName , istream ); - } catch ( X_SRDErrors const& srbErrors ) { - errors.addAll( srbErrors.errors ); - } - data.top( ).output( ).addAll( tgt.list( ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Get ) -{ - auto& data( state.data( ) ); - auto& input( state.output( ) ); - const auto sz( input.size( ) ); - auto& output( state.data( ).top( ).output( ) ); - - for ( uint32_t i = 0 ; i < sz ; i ++ ) { - auto const& vtok( input[ i ] ); - if ( vtok.type( ) != E_SRDTokenType::WORD ) { - data.addError( vtok , "word expected" ); - continue; - } - - auto var( data.scopes( ).get( false , vtok.stringValue( ) ) ); - if ( var == nullptr ) { - data.addError( vtok , "unknown variable" ); - } else { - output.addAll( *var ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( If ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - const auto sz( input.size( ) ); - - if ( sz < 2 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( sz > 3 ) { - data.addError( loc , "too many arguments" ); - return; - } - - auto const& cdTok( input[ 0 ] ); - if ( cdTok.type( ) != E_SRDTokenType::INT && cdTok.type( ) != E_SRDTokenType::LONG ) { - data.addError( cdTok , "integer expected" ); - return; - } - if ( input[ 1 ].type( ) != E_SRDTokenType::LIST ) { - data.addError( input[ 1 ] , "list expected" ); - return; - } - if ( sz == 3 && input[ 2 ].type( ) != E_SRDTokenType::LIST ) { - data.addError( input[ 2 ] , "list expected" ); - return; - } - - const bool cond( cdTok.longValue( ) != 0 ); - if ( sz == 2 && !cond ) { - return; - } - data.push( T_SRDPreprocessorState::C_INNER , - NewShared< T_SRDList >( input[ cond ? 1 : 2 ].list( ) ) , - data.top( ).outputPointer( ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Ignore ) -{ - (void) state; -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( IsBlessed ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - bool blessed; - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - blessed = false; - } else if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - blessed = false; - } else if ( input[ 0 ].type( ) != E_SRDTokenType::WORD ) { - data.addError( input[ 0 ] , "word expected" ); - blessed = false; - } else { - blessed = data.scopes( ).isBlessed( input[ 0 ].stringValue( ) ); - } - T_SRDToken output( T_SRDToken::Integer( blessed ? 1 : 0 ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( IsMacro ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - bool set; - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - set = false; - } else if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - set = false; - } else if ( input[ 0 ].type( ) != E_SRDTokenType::WORD ) { - data.addError( input[ 0 ] , "word expected" ); - set = false; - } else { - set = ( data.scopes( ).get( true , input[ 0 ].stringValue( ) ) != nullptr ); - } - T_SRDToken output( T_SRDToken::Integer( set ? 1 : 0 ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( IsSet ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - bool set; - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - set = false; - } else if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - set = false; - } else if ( input[ 0 ].type( ) != E_SRDTokenType::WORD ) { - data.addError( input[ 0 ] , "word expected" ); - set = false; - } else { - set = ( data.scopes( ).get( false , input[ 0 ].stringValue( ) ) != nullptr ); - } - T_SRDToken output( T_SRDToken::Integer( set ? 1 : 0 ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Length ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - int64_t length; - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - length = -1; - } else if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - length = -1; - } else if ( input[ 0 ].type( ) == E_SRDTokenType::LIST ) { - length = input[ 0 ].list( ).size( ); - } else if ( input[ 0 ].type( ) == E_SRDTokenType::BINARY ) { - length = input[ 0 ].binary( ).size( ); - } else if ( input[ 0 ].isText( ) ) { - length = input[ 0 ].stringValue( ).length( ); - } else { - data.addError( input[ 0 ] , "list, word, string or binary array expected" ); - length = -1; - } - - T_SRDToken output( T_SRDToken::AutoInteger( length ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( ListMacros ) -{ - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - if ( state.output( ).size( ) != 0 ) { - data.addError( loc , "too many arguments" ); - } - - auto & output( data.top( ).output( ) ); - T_Array< T_String > macroNames( data.scopes( ).list( true ) ); - const auto nMacros( macroNames.size( ) ); - for ( uint32_t i = 0 ; i < nMacros ; i ++ ) { - T_SRDToken tok( T_SRDToken::Word( macroNames[ i ] ) ); - tok.location( loc ); - output.add( std::move( tok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( ListVariables ) -{ - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - if ( state.output( ).size( ) != 0 ) { - data.addError( loc , "too many arguments" ); - } - - auto & output( data.top( ).output( ) ); - T_Array< T_String > varNames( data.scopes( ).list( false ) ); - const auto nVars( varNames.size( ) ); - for ( uint32_t i = 0 ; i < nVars ; i ++ ) { - T_SRDToken tok( T_SRDToken::Word( varNames[ i ] ) ); - tok.location( loc ); - output.add( std::move( tok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Mod ) -{ - DoMathOp_( state , - []( auto a , auto b ) { - return a % b; - } , - []( auto a , auto b ) { - return std::fmod( a , b ); - } , true ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Mul ) -{ - DoMathOp_( state , - []( auto a , auto b ) { - return a * b; - } , - []( auto a , auto b ) { - return a * b; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Neg ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - bool of( false ); - int64_t iv( 0 ); - double fv( 0 ); - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) != 1 ) { - data.addError( loc , "too many arguments" ); - } else if ( !input[ 0 ].isNumeric( ) ) { - data.addError( input[ 0 ] , "numeric argument expected" ); - } else if ( input[ 0 ].isInteger( ) ) { - iv = -input[ 0 ].longValue( ); - } else { - fv = -input[ 0 ].floatValue( ); - of = true; - } - - T_SRDToken output( of ? T_SRDToken::Float( fv ) : T_SRDToken::AutoInteger( iv ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Not ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - int64_t iv( 0 ); - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) != 1 ) { - data.addError( loc , "too many arguments" ); - } else if ( !input[ 0 ].isInteger( ) ) { - data.addError( input[ 0 ] , "integer argument expected" ); - } else { - iv = input[ 0 ].longValue( ) ? 0 : 1; - } - - T_SRDToken output( T_SRDToken::Integer( iv ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Or ) -{ - DoLogicOp_( state , - []( auto a , auto b ) { - return ( a || b ) ? 1 : 0; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Output ) -{ - auto& out( state.output( ) ); - const auto n( out.size( ) ); - - if ( n ) { - auto& data( state.data( ) ); - auto& pp( data.preprocessor( ) ); - auto& ec( data.errorContext( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - pp.sendOutput( ec , out[ i ] ); - } - pp.target( ).push( ec , T_SRDToken::Flush( ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Raw ) -{ - state.data( ).top( ).output( ).addAll( state.output( ) ); -} - -/*----------------------------------------------------------------------------*/ - -namespace { - -void RethrowError_( T_SRDPreprocessorData& data , T_SRDList const& error ) -{ - auto const& esTok( error[ 0 ] ); - if ( esTok.type( ) != E_SRDTokenType::STRING ) { - data.addError( esTok , "string expected" ); - return; - } - - const auto elSize( error.size( ) ); - SP_SRDLocation location; - for ( uint32_t i = elSize - 1 ; i > 0 ; i -- ) { - auto const& locEntry( error[ i ] ); - if ( locEntry.type( ) != E_SRDTokenType::LIST ) { - data.addError( locEntry , "list expected" ); - return; - } - - auto const& locList( locEntry.list( ) ); - const bool hasChaining( i != elSize - 1 ); - const uint32_t expectedLength( hasChaining ? 4 : 3 ); - if ( locList.size( ) != expectedLength ) { - data.addError( locEntry , "invalid location entry" ); - return; - } - - auto const& locName( locList[ 0 ] ); - if ( locName.type( ) != E_SRDTokenType::STRING ) { - data.addError( locName , "string expected" ); - return; - } - auto const& locLine( locList[ 1 ] ); - if ( !locLine.isInteger( ) ) { - data.addError( locLine , "integer expected" ); - return; - } - const int64_t line( locLine.longValue( ) ); - if ( line < 0 || line > UINT32_MAX ) { - data.addError( locLine , "invalid line number" ); - return; - } - - auto const& locChar( locList[ 2 ] ); - if ( !locChar.isInteger( ) ) { - data.addError( locChar , "integer expected" ); - return; - } - const int64_t character( locChar.longValue( ) ); - if ( character < 0 || character > UINT32_MAX ) { - data.addError( locChar , "invalid character/byte number" ); - return; - } - - E_SRDLocationChaining chaining; - if ( hasChaining ) { - if ( locList[ 3 ].type( ) != E_SRDTokenType::WORD ) { - data.addError( locList[ 3 ] , "word expected" ); - return; - } - T_String const& chainWord( locList[ 3 ].stringValue( ) ); - if ( chainWord == "generated" ) { - chaining = E_SRDLocationChaining::GENERATED; - } else if ( chainWord == "included" ) { - chaining = E_SRDLocationChaining::INCLUDED; - } else if ( chainWord == "loaded" ) { - chaining = E_SRDLocationChaining::LOADED; - } else if ( chainWord == "called" ) { - chaining = E_SRDLocationChaining::CALLED; - } else if ( chainWord == "evaluated" ) { - chaining = E_SRDLocationChaining::EVALUATED; - } else if ( chainWord == "expanded" ) { - chaining = E_SRDLocationChaining::EXPANDED; - } else if ( chainWord == "substituted" ) { - chaining = E_SRDLocationChaining::SUBSTITUTED; - } else { - data.addError( locList[ 3 ] , "invalid chaining" ); - return; - } - } else { - // Compiler stfu - chaining = E_SRDLocationChaining( 0 ); - } - - T_String const& src( locName.stringValue( ) ); - SP_SRDLocation nLocation( line > 0 - ? NewShared< T_SRDLocation >( src , line , character ) - : NewShared< T_SRDLocation >( src , character ) ); - if ( hasChaining ) { - nLocation->chain( chaining , location ); - } - location = nLocation; - } - - data.addError( *location , esTok.stringValue( ) ); -} - -void DoRethrow_( T_SRDPreprocessorData& data , T_SRDList const& errors ) -{ - const auto nErrors( errors.size( ) ); - for ( uint32_t i = 0 ; i < nErrors ; i ++ ) { - auto const& errTok( errors[ i ] ); - if ( errTok.type( ) != E_SRDTokenType::LIST ) { - data.addError( errTok , "list expected" ); - continue; - } - if ( errTok.list( ).size( ) < 2 ) { - data.addError( errTok , "invalid error record" ); - continue; - } - RethrowError_( data , errTok.list( ) ); - } -} - -} - -M_SRDPP_COMMAND_EXEC( Rethrow ) -{ - auto const& input( state.output( ) ); - if ( input.size( ) == 0 ) { - return; - } - if ( input.size( ) == 1 && input[ 0 ].type( ) == E_SRDTokenType::LIST ) { - auto const& innerList( input[ 0 ].list( ) ); - if ( innerList.size( ) == 0 ) { - return; - } - if ( innerList[ 0 ].type( ) == E_SRDTokenType::LIST ) { - DoRethrow_( state.data( ) , innerList ); - return; - } - } - DoRethrow_( state.data( ) , input ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Scope ) -{ - if ( state.output( ).size( ) == 0 ) { - return; - } - auto& data( state.data( ) ); - data.scopes( ).enter( ); - data.push( T_SRDPreprocessorState::C_INNER , - state.outputPointer( ) , data.top( ).outputPointer( ) , - []( T_SRDPreprocessorState & ns ) { - ns.data( ).scopes( ).exit( ); - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Set ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - - auto const& names( input[ 0 ] ); - auto& s( data.scopes( ) ); - if ( names.type( ) == E_SRDTokenType::WORD ) { - auto const& vn( names.stringValue( ) ); - if ( !s.canSet( false , vn ) ) { - data.addError( names , "duplicate variable name" ); - return; - } - s.set( false , vn , input , 1 ); - - } else if ( names.type( ) == E_SRDTokenType::LIST ) { - auto const& list( names.list( ) ); - const auto n( list.size( ) ); - if ( n == 0 ) { - data.addError( names , "non-empty list expected" ); - return; - } - - bool ok( true ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto const& name( list[ i ] ); - if ( name.type( ) != E_SRDTokenType::WORD ) { - data.addError( name , "word expected" ); - ok = false; - continue; - } - - auto const& vn( name.stringValue( ) ); - for ( uint32_t j = 0 ; j < i ; j ++ ) { - if ( list[ j ].type( ) != E_SRDTokenType::WORD ) { - continue; - } - if ( list[ j ].stringValue( ) == vn ) { - data.addError( name , "duplicate variable name" ); - ok = false; - goto next; - } - } - if ( !s.canSet( false , vn ) ) { - data.addError( name , "duplicate variable name" ); - ok = false; - } - -next: ; - } - - if ( !ok ) { - return; - } - for ( uint32_t i = 0 ; i + 1 < n ; i ++ ) { - s.set( false , list[ i ].stringValue( ) , input , 1 + i , 1 + i ); - } - s.set( false , list[ n - 1 ].stringValue( ) , input , n ); - - } else { - data.addError( names , "word or list expected" ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( SetMacro ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) < 2 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( input.size( ) > 2 ) { - data.addError( loc , "too many arguments" ); - return; - } - - auto const& name( input[ 0 ] ); - if ( name.type( ) != E_SRDTokenType::WORD ) { - data.addError( name , "word expected" ); - return; - } - auto const& mn( name.stringValue( ) ); - auto& s( data.scopes( ) ); - if ( !s.canSet( true , mn ) ) { - data.addError( name , "duplicate macro name" ); - return; - } - - auto const& value( input[ 1 ] ); - if ( !T_SRDPreprocessor::isValidFunction( value ) ) { - data.addError( value , "invalid macro body" ); - return; - } - - s.set( true , mn , value.list( ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( StartsWith ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - uint32_t value = 0; - if ( input.size( ) < 2 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) > 2 ) { - data.addError( loc , "too many arguments" ); - } else { - if ( input[ 0 ].isText( ) && input[ 1 ].isText( ) ) { - value = input[ 1 ].stringValue( ).startsWith( - input[ 0 ].stringValue( ) ); - } else if ( input[ 0 ].type( ) == E_SRDTokenType::BINARY - && input[ 1 ].type( ) == E_SRDTokenType::BINARY ) { - auto const& needle( input[ 0 ].binary( ) ); - auto const& haystack( input[ 1 ].binary( ) ); - auto const nsz( needle.size( ) ); - auto const hsz( haystack.size( ) ); - value = ( nsz <= hsz - && !( nsz && memcmp( needle.data( ) , - haystack.data( ) , nsz ) ) ); - } else { - data.addError( loc , "invalid arguments" ); - } - } - - auto tok( T_SRDToken::Integer( value ) ); - tok.location( loc ); - data.top( ).output( ).add( std::move( tok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( StrFind ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - int32_t value = -1; - if ( input.size( ) < 2 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) > 2 ) { - data.addError( loc , "too many arguments" ); - } else { - if ( !input[ 0 ].isText( ) ) { - data.addError( input[ 0 ] , "text expected" ); - } - if ( !input[ 1 ].isText( ) ) { - data.addError( input[ 1 ] , "text expected" ); - } - if ( input[ 0 ].isText( ) && input[ 1 ].isText( ) ) { - value = input[ 1 ].stringValue( ).find( - input[ 0 ].stringValue( ) ); - } - } - - auto tok( T_SRDToken::Integer( value ) ); - tok.location( loc ); - data.top( ).output( ).add( std::move( tok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( StrSplit ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - auto& output( data.top( ).output( ) ); - - if ( input.size( ) < 2 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( input.size( ) > 3 ) { - data.addError( loc , "too many arguments" ); - return; - } - - bool argsOk = true; - if ( !input[ 0 ].isText( ) ) { - data.addError( input[ 0 ] , "text expected" ); - argsOk = false; - } else if ( !input[ 0 ].stringValue( ) ) { - data.addError( input[ 0 ] , "invalid argument value" ); - argsOk = false; - } - if ( !input[ 1 ].isText( ) ) { - data.addError( input[ 1 ] , "text expected" ); - argsOk = false; - } - if ( input.size( ) == 3 - && input[ 2 ].type( ) != E_SRDTokenType::INT - && input[ 2 ].type( ) != E_SRDTokenType::LONG ) { - data.addError( input[ 2 ] , "integer expected" ); - argsOk = false; - } - if ( !argsOk ) { - return; - } - uint32_t maxOutput; - if ( input.size( ) == 3 ) { - int64_t n( input[ 2 ].longValue( ) ); - if ( n < 0 || n > UINT32_MAX ) { - data.addError( input[ 2 ] , "invalid argument value" ); - maxOutput = UINT32_MAX; - } else { - maxOutput = n; - } - } else { - maxOutput = UINT32_MAX; - } - - int32_t nextSearch( 0 ); - auto const& needle( input[ 0 ].stringValue( ) ); - auto const& haystack( input[ 1 ].stringValue( ) ); - while ( nextSearch != -1 && maxOutput != 0 ) { - const int32_t sepIndex( haystack.find( needle , nextSearch ) ); - - const T_String os( sepIndex == -1 - ? haystack.substr( nextSearch ) - : ( sepIndex == 0 - ? T_String( ) - : haystack.range( nextSearch , sepIndex - 1 ) ) ); - T_SRDToken otok( T_SRDToken::String( os ) ); - otok.location( loc ); - output.add( std::move( otok ) ); - - if ( sepIndex == -1 ) { - nextSearch = -1; - } else { - nextSearch = sepIndex + needle.length( ); - } - maxOutput --; - } - - if ( maxOutput == 0 && nextSearch != -1 ) { - T_SRDToken otok( T_SRDToken::String( haystack.substr( nextSearch ) ) ); - otok.location( loc ); - output.add( std::move( otok ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Sub ) -{ - DoMathOp_( state , - []( auto a , auto b ) { - return a - b; - } , - []( auto a , auto b ) { - return a - b; - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Substr ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - const auto is( input.size( ) ); - if ( is < 2 ) { - data.addError( loc , "not enough arguments" ); - } else if ( is > 4 ) { - data.addError( loc , "too many arguments" ); - } - if ( is == 0 ) { - T_SRDToken otok( T_SRDToken::String( T_String( ) ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); - return; - } - - const bool isBinary( input[ 0 ].type( ) == E_SRDTokenType::BINARY ); - if ( is < 2 || is > 4 ) { - T_SRDToken otok( isBinary - ? T_SRDToken::Binary( (uint8_t const*) nullptr , 0 ) - : T_SRDToken::String( T_String( ) ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); - return; - } - - const bool isRange = ( is == 4 ); - bool argsOk = true; - uint32_t start( 0 ); - uint32_t end( UINT32_MAX ); - - if ( !( input[ 0 ].isText( ) || isBinary ) ) { - data.addError( input[ 0 ] , "binary or text expected" ); - argsOk = false; - } - - if ( isRange && ( input[ 2 ].type( ) != E_SRDTokenType::WORD - || input[ 2 ].stringValue( ) != "to" ) ) { - data.addError( input[ 2 ] , "'to' expected" ); - argsOk = false; - } - - if ( !input[ 1 ].isNumeric( ) || input[ 1 ].type( ) == E_SRDTokenType::FLOAT ) { - data.addError( input[ 1 ] , "integer expected" ); - argsOk = false; - } else { - const int64_t v( input[ 1 ].longValue( ) ); - if ( v < 0 || v > UINT32_MAX ) { - data.addError( input[ 1 ] , "invalid argument value" ); - argsOk = false; - } else { - start = v; - } - } - - if ( is > 2 ) { - auto const& next( input[ isRange ? 3 : 2 ] ); - if ( !next.isNumeric( ) || next.type( ) == E_SRDTokenType::FLOAT ) { - data.addError( next , "integer expected" ); - argsOk = false; - } else { - const int64_t v( next.longValue( ) ); - if ( v < 0 || v > UINT32_MAX ) { - data.addError( next , "invalid argument value" ); - argsOk = false; - } else { - end = v; - } - } - } - - if ( !argsOk ) { - T_SRDToken otok( isBinary - ? T_SRDToken::Binary( (uint8_t const*) nullptr , 0 ) - : T_SRDToken::String( T_String( ) ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); - return; - } - - if ( !isBinary ) { - auto const& str( input[ 0 ].stringValue( ) ); - T_SRDToken otok( T_SRDToken::String( isRange - ? str.range( start , end ) - : str.substr( start , end ) ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); - return; - } - - const uint32_t oriLen( input[ 0 ].binary( ).size( ) ); - const uint32_t realEnd( std::min( oriLen , end ) ); - const uint32_t lengthMax( isRange - ? ( realEnd < start ? 0 : realEnd - start + 1 ) - : realEnd ); - const uint32_t length( start >= oriLen - ? 0 : ( std::min( oriLen , start + lengthMax ) - start ) ); - auto buffer( NewShared< T_Buffer< uint8_t > >( length ) ); - if ( length ) { - memcpy( buffer->data( ) , input[ 0 ].binary( ).data( ) , length ); - } - T_SRDToken otok( T_SRDToken::Binary( buffer ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( ToSource ) -{ - auto& input( state.output( ) ); - const auto n( input.size( ) ); - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < n ; i ++ ) { - if ( i > 0 ) { - sb << ' '; - } - - auto& token( input[ i ] ); - token.generateFullText( ); - sb << token.fullText( ); - } - - T_SRDToken otok( T_SRDToken::String( std::move( sb ) ) ); - otok.location( *state.initialLocation( ) ); - state.data( ).top( ).output( ).add( std::move( otok ) ); -} - -/*----------------------------------------------------------------------------*/ - -namespace { - -void ErrorsToList_( T_SRDLocation const& location , T_SRDErrors const& errors , T_SRDList & output ) -{ - const auto nErrors( errors.size( ) ); - for ( uint32_t i = 0 ; i < nErrors ; i ++ ) { - auto const& error( errors[ i ] ); - auto& errToken( output[ output.add( T_SRDToken::List( ) ) ] ); - auto& etl( errToken.list( ) ); - errToken.location( location ); - - { - T_SRDToken msg( T_SRDToken::String( error.error( ) ) ); - msg.location( location ); - etl.add( std::move( msg ) ); - } - - RPC_SRDLocation errLoc( &error.location( ) ); - RPC_SRDLocationChaining chaining( nullptr ); - while ( errLoc != nullptr ) { - auto& locToken( etl[ etl.add( T_SRDToken::List( ) ) ] ); - auto& ll( locToken.list( ) ); - locToken.location( location ); - - { - T_SRDToken src( T_SRDToken::String( errLoc->source( ) ) ); - src.location( location ); - ll.add( std::move( src ) ); - }{ - T_SRDToken ln( T_SRDToken::Integer( errLoc->line( ) ) ); - ln.location( location ); - ll.add( std::move( ln ) ); - }{ - T_SRDToken cn( T_SRDToken::Integer( errLoc->character( ) ) ); - cn.location( location ); - ll.add( std::move( cn ) ); - } - if ( chaining ) { - T_String chain( T_String::Pooled( ( []( RPC_SRDLocationChaining c ) -> char const* { - switch ( c->circumstances ) { - case E_SRDLocationChaining::INCLUDED: - return "included"; - case E_SRDLocationChaining::LOADED: - return "loaded"; - case E_SRDLocationChaining::CALLED: - return "called"; - case E_SRDLocationChaining::GENERATED: - return "generated"; - case E_SRDLocationChaining::SUBSTITUTED: - return "substituted"; - case E_SRDLocationChaining::EVALUATED: - return "evaluated"; - case E_SRDLocationChaining::EXPANDED: - return "expanded"; - } - return "unknown"; - } )( chaining ) ) ); - - T_SRDToken ctok( T_SRDToken::Word( std::move( chain ) ) ); - ctok.location( location ); - ll.add( std::move( ctok ) ); - } - - if ( errLoc->isChained( ) ) { - chaining = &errLoc->chaining( ); - errLoc = RPC_SRDLocation( chaining->location ); - } else { - errLoc = nullptr; - } - } - } -} - -} - -M_SRDPP_COMMAND_EXEC( Try ) -{ - auto& data( state.data( ) ); - auto& output( data.top( ).output( ) ); - - T_SRDToken otok( T_SRDToken::List( ) ); - otok.location( *state.initialLocation( ) ); - if ( state.output( ).size( ) == 0 ) { - // No input -> empty list - output.add( std::move( otok ) ); - return; - } - - const SP_SRDList fullOutput( NewShared< T_SRDList >( 16 ) ); - fullOutput->add( std::move( otok ) ); - - data.pushErrorContext( ); - data.push( T_SRDPreprocessorState::C_TRY , state.outputPointer( ) , fullOutput , - []( T_SRDPreprocessorState & ns ) { - const RP_SRDErrors errors( ns.data( ).popErrorContext( ) ); - auto& errTok( ns.output( )[ 0 ] ); - ErrorsToList_( errTok.location( ) , *errors , errTok.list( ) ); - delete errors; - ns.data( ).top( ).output( ).addAll( std::move( ns.output( ) ) ); - } ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( TypeOf ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - char const* type; - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - type = "none"; - } else if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - type = "none"; - } else { - switch ( input[ 0 ].type( ) ) { - case E_SRDTokenType::LIST: - type = "list"; - break; - - case E_SRDTokenType::WORD: - type = "word"; - break; - - case E_SRDTokenType::STRING: - type = "string"; - break; - - case E_SRDTokenType::INT: - type = "int"; - break; - - case E_SRDTokenType::LONG: - type = "long"; - break; - - case E_SRDTokenType::FLOAT: - type = "real"; - break; - - case E_SRDTokenType::VAR: - type = "var"; - break; - - case E_SRDTokenType::BINARY: - type = "binary"; - break; - - case E_SRDTokenType::COMMENT: - type = "comment"; - break; - - default: - type = "none"; - data.addError( input[ 0 ] , "internal error" ); - break; - } - } - - T_SRDToken output( T_SRDToken::Word( T_String::Pooled( type ) ) ); - output.location( loc ); - state.data( ).top( ).output( ).add( std::move( output ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Unset ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - - const uint32_t n( input.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto const& name( input[ i ] ); - if ( name.type( ) != E_SRDTokenType::WORD ) { - data.addError( name , "word expected" ); - } else { - data.scopes( ).unset( false , name.stringValue( ) ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( UnsetMacro ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - - const uint32_t n( input.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto const& name( input[ i ] ); - if ( name.type( ) != E_SRDTokenType::WORD ) { - data.addError( name , "word expected" ); - } else { - data.scopes( ).unset( true , name.stringValue( ) ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Unwrap ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - } else if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - } else if ( input[ 0 ].type( ) != E_SRDTokenType::LIST ) { - data.addError( input[ 0 ] , "list expected" ); - } else { - data.top( ).output( ).addAll( std::move( input[ 0 ].list( ) ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( Xor ) -{ - DoLogicOp_( state , - []( auto a , auto b ) { - return ( a || b ) && !( a && b ); - } ); -} - - -/*= VFS COMMANDS =============================================================*/ - -M_SRDPP_COMMAND_EXEC( VFSList ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - return; - } - if ( input[ 0 ].type( ) != E_SRDTokenType::STRING ) { - data.addError( input[ 0 ] , "string expected" ); - return; - } - - const T_VFSPath path( input[ 0 ].stringValue( ) ); - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - data.addError( input[ 0 ] , "absolute VFS path expected" ); - return; - } - - T_Array< T_VFSPath > list( 32 ); - if ( !vfs_.list( path , list ) ) { - return; - } - - const uint32_t n( list.size( ) ); - T_SRDList output( std::max( 1u , n ) ); - output.ensureCapacity( n ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - output.add( T_SRDToken::String( T_String( list[ i ] ) ) ); - } - - auto otok( T_SRDToken::List( std::move( output ) ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( VFSLoad ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - auto const& loc( *state.initialLocation( ) ); - - if ( input.size( ) == 0 ) { - data.addError( loc , "not enough arguments" ); - return; - } - if ( input.size( ) > 1 ) { - data.addError( loc , "too many arguments" ); - return; - } - if ( input[ 0 ].type( ) != E_SRDTokenType::STRING ) { - data.addError( input[ 0 ] , "string expected" ); - return; - } - - const T_VFSPath path( input[ 0 ].stringValue( ) ); - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - data.addError( input[ 0 ] , "absolute VFS path expected" ); - return; - } - - const OP_InputStream istream( vfs_.read( path ) ); - if ( !istream ) { - T_StringBuilder sb( "error while loading '" ); - sb << T_String( path ) << "': file not found"; - data.addError( input[ 0 ] , std::move( sb ) ); - return; - } - - T_SharedPtr< T_Buffer< uint8_t > > buffer; - try { - if ( istream->isSizeKnown( ) ) { - const auto sz( istream->size( ) ); - buffer = NewShared< T_Buffer< uint8_t > >( sz ); - if ( sz ) { - istream->read( buffer->data( ) , sz ); - } - } else { - uint8_t temp[ 4096 ]; - buffer = NewShared< T_Buffer< uint8_t > >( ); - try { - while ( 1 ) { - const auto nRead( istream->read( temp , sizeof( temp ) ) ); - const auto prevSize( buffer->size( ) ); - assert( nRead > 0 ); - buffer->resize( prevSize + nRead ); - memcpy( buffer->data( ) + prevSize , temp , nRead ); - } - } catch ( X_StreamError const& error ) { - if ( error.code( ) != E_StreamError::END ) { - throw; - } - } - } - } catch ( X_StreamError const& error ) { - T_StringBuilder sb( "error while loading '" ); - sb << T_String( path ) << "': " << error.what( ); - data.addError( input[ 0 ] , std::move( sb ) ); - } - - auto otok( T_SRDToken::Binary( buffer ) ); - otok.location( loc ); - data.top( ).output( ).add( std::move( otok ) ); -} - -/*----------------------------------------------------------------------------*/ - -M_SRDPP_COMMAND_EXEC( VFSType ) -{ - auto& input( state.output( ) ); - auto& data( state.data( ) ); - - const auto is( input.size( ) ); - if ( is == 0 ) { - return; - } - - T_Array< T_VFSPath > paths( 4 ); - paths.ensureCapacity( is ); - for ( uint32_t i = 0 ; i < is ; i ++ ) { - if ( input[ i ].type( ) != E_SRDTokenType::STRING ) { - data.addError( input[ i ] , "string expected" ); - return; - } - - T_VFSPath const& path( paths.addNew( input[ i ].stringValue( ) ) ); - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - data.addError( input[ i ] , "absolute VFS path expected" ); - return; - } - } - - auto& out( data.top( ).output( ) ); - for ( uint32_t i = 0 ; i < is ; i ++ ) { - const E_VFSEntryType et( vfs_.typeOf( paths[ i ] ) ); - T_SRDToken token( ( []( E_VFSEntryType et ) { - switch ( et ) { - case E_VFSEntryType::NONE: - return T_SRDToken::Word( T_String::Pooled( "none" ) ); - - case E_VFSEntryType::FILE: - return T_SRDToken::Word( T_String::Pooled( "file" ) ); - - case E_VFSEntryType::DIRECTORY: - return T_SRDToken::Word( T_String::Pooled( "directory" ) ); - - case E_VFSEntryType::OTHER: - return T_SRDToken::Word( T_String::Pooled( "other" ) ); - } - return T_SRDToken::Word( T_String::Pooled( "unknown" ) ); - })( et ) ); - token.copyLocationOf( input[ i ] ); - out.add( std::move( token ) ); - } -} diff --git a/src/SRDParser.cc b/src/SRDParser.cc index 2858ba3..fe1eea4 100644 --- a/src/SRDParser.cc +++ b/src/SRDParser.cc @@ -3,8 +3,8 @@ /******************************************************************************/ -#include -using namespace lw; +#include +using namespace ebcl; /*= T_SRDParserData ==========================================================*/ diff --git a/src/SRDParserConfig.cc b/src/SRDParserConfig.cc index bb5b0c4..b8d8644 100644 --- a/src/SRDParserConfig.cc +++ b/src/SRDParserConfig.cc @@ -2,8 +2,8 @@ /* SRD - PARSER CONFIGURATION *************************************************/ /******************************************************************************/ -#include -using namespace lw; +#include +using namespace ebcl; namespace { diff --git a/src/SRDPreproc.cc b/src/SRDPreproc.cc deleted file mode 100644 index 1909be8..0000000 --- a/src/SRDPreproc.cc +++ /dev/null @@ -1,1416 +0,0 @@ -/******************************************************************************/ -/* SRD - PREPROCESSOR *********************************************************/ -/******************************************************************************/ - -#include -#include -#include -using namespace lw; - - -/*= A_SRDPreprocessorCommand =================================================*/ - -A_SRDPreprocessorCommand::~A_SRDPreprocessorCommand( ) -{ } - - -/*= T_SRDPreprocessorConfig ==================================================*/ - -T_SRDPreprocessorConfig::T_SRDPreprocessorConfig( ) - : commands_( []( OP_SRDPreprocessorCommand const& cmd ) -> T_String const& { - return cmd->command( ); - } ) -{ } - -T_SRDPreprocessorConfig& T_SRDPreprocessorConfig::add( - OP_SRDPreprocessorCommand&& command ) -{ - commands_.add( std::move( command ) ); - return *this; -} - -RPC_SRDPreprocessorCommand T_SRDPreprocessorConfig::command( - T_String const& name ) const -{ - const auto cmd( commands_.get( name ) ); - if ( cmd == nullptr ) { - return nullptr; - } - return cmd->get( ); -} - - -/*= T_SRDPPStateImpl_ ========================================================*/ - -namespace { -struct T_SRDPPStateImpl_ -{ - using E_Type = T_SRDPreprocessorState::E_Type; - - // --------------------------------------------------------------------- - - T_SRDPreprocessorData& data_; - - SP_SRDList input_; - uint32_t pos_; - - SP_SRDList output_; - SP_SRDLocation initialLocation_; - - F_SRDPreprocessorHandler postExec_; - - uint32_t processLimit_; - bool rawMode_; - T_Array< T_SRDToken > rawStack_; - - T_SRDPreprocessorState::E_Type type_; - uint8_t exiting_; - - // --------------------------------------------------------------------- - - explicit T_SRDPPStateImpl_( - T_SRDPreprocessorData& data ) noexcept; - - T_SRDPPStateImpl_( - T_SRDPreprocessorData& data , - E_Type type , - SP_SRDList&& input ) noexcept; - - T_SRDPPStateImpl_( - T_SRDPreprocessorData& data , - E_Type type , - SP_SRDList&& input , - SP_SRDList&& output , - F_SRDPreprocessorHandler postExec ) noexcept; - - // --------------------------------------------------------------------- -}; -} - -/*----------------------------------------------------------------------------*/ - -inline T_SRDPPStateImpl_::T_SRDPPStateImpl_( - T_SRDPreprocessorData& data ) noexcept - : T_SRDPPStateImpl_( data , T_SRDPreprocessorState::C_UNSPECIFIED , {} ) -{ } - -inline T_SRDPPStateImpl_::T_SRDPPStateImpl_( - T_SRDPreprocessorData& data , - const E_Type type , - SP_SRDList&& input ) noexcept - : T_SRDPPStateImpl_( data , type , std::move( input ) , - NewShared< T_SRDList >( 32 ) , {} ) -{ } - -inline T_SRDPPStateImpl_::T_SRDPPStateImpl_( - T_SRDPreprocessorData& data , - const E_Type type , - SP_SRDList&& input , - SP_SRDList&& output , - F_SRDPreprocessorHandler postExec ) noexcept - : data_( data ) , - // - input_( std::move( input ) ) , - pos_( 0 ) , - // - output_( std::move( output ) ) , - initialLocation_( ) , - // - postExec_( postExec ) , - // - processLimit_( UINT32_MAX ) , - rawMode_( false ) , - rawStack_( 16 ) , - // - type_( type ) , - exiting_( 0 ) -{ } - - - -/*= T_SRDPreprocessorState ===================================================*/ - -T_SRDPreprocessorState::T_SRDPreprocessorState( - T_SRDPreprocessorData& data ) - : A_PrivateImplementation( new T_SRDPPStateImpl_( data ) ) -{ } - -T_SRDPreprocessorState::T_SRDPreprocessorState( - T_SRDPreprocessorData& data , - const E_Type type , - SP_SRDList input ) - : A_PrivateImplementation( new T_SRDPPStateImpl_( - data , type , std::move( input ) ) ) -{ } - -T_SRDPreprocessorState::T_SRDPreprocessorState( - T_SRDPreprocessorData& data , - const E_Type type , - SP_SRDList input , - SP_SRDList output , - F_SRDPreprocessorHandler postExec ) - : A_PrivateImplementation( new T_SRDPPStateImpl_( - data , type , std::move( input ) , - std::move( output ) , postExec ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -T_SRDPreprocessorData& T_SRDPreprocessorState::data( ) const -{ - return p< T_SRDPPStateImpl_ >( ).data_; -} - -bool T_SRDPreprocessorState::hasInput( ) const -{ - return bool( p< T_SRDPPStateImpl_ >( ).input_ ); -} - -bool T_SRDPreprocessorState::isFinished( ) const -{ - auto const& pi( p< T_SRDPPStateImpl_ >( ) ); - return !pi.input_ || pi.pos_ >= pi.input_->size( ); -} - -T_SRDList& T_SRDPreprocessorState::output( ) const -{ - return *( p< T_SRDPPStateImpl_ >( ).output_ ); -} - -SP_SRDList const& T_SRDPreprocessorState::outputPointer( ) const -{ - return p< T_SRDPPStateImpl_ >( ).output_; -} - -RPC_SRDLocation T_SRDPreprocessorState::initialLocation( ) const -{ - return RPC_SRDLocation( p< T_SRDPPStateImpl_ >( ).initialLocation_ ); -} - -T_SRDPreprocessorState::E_Type T_SRDPreprocessorState::type( ) const -{ - return p< T_SRDPPStateImpl_ >( ).type_; -} - -void T_SRDPreprocessorState::setExiting( E_Type type ) -{ - auto& e( p< T_SRDPPStateImpl_ >( ).exiting_ ); - e = e | uint8_t( type ); -} - -uint8_t T_SRDPreprocessorState::isExiting( ) const -{ - return p< T_SRDPPStateImpl_ >( ).exiting_; -} - -/*----------------------------------------------------------------------------*/ - -SP_SRDLocation T_SRDPreprocessorState::createChainedLocation( ) const -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - SP_SRDLocation cloc( pi.data_.callLocation( ) ); - if ( pi.initialLocation_ && cloc ) { - SP_SRDLocation location( NewShared< T_SRDLocation >( *pi.initialLocation_ ) ); - if ( location->isChained( ) ) { - auto& lc( location->chaining( ) ); - SP_SRDLocation ptrInitial( cloc ); - SP_SRDLocation ptrNew( NewShared< T_SRDLocation >( *cloc ) ); - cloc = ptrNew; - while ( ptrInitial ) { - if ( ptrInitial->isChained( ) ) { - auto& chain( ptrInitial->chaining( ) ); - SP_SRDLocation ptrNext( NewShared< T_SRDLocation >( - *( chain.location ) ) ); - if ( chain.depth > 1 ) { - ptrNew->chain( chain.circumstances , chain.depth , ptrNext ); - } else { - ptrNew->chain( chain.circumstances , ptrNext ); - } - ptrNew = ptrNext; - ptrInitial = chain.location; - } else { - if ( lc.depth > 1 ) { - ptrNew->chain( lc.circumstances , lc.depth , lc.location ); - } else { - ptrNew->chain( lc.circumstances , lc.location ); - } - ptrInitial = SP_SRDLocation( ); - } - } - } - location->chain( E_SRDLocationChaining::CALLED , pi.data_.callRecursionDepth( ) , cloc ); - return location; - } else if ( pi.initialLocation_ ) { - return pi.initialLocation_; - } else { - return cloc; - } -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorState::processToken( - T_SRDToken& token ) -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - if ( token.type( ) != E_SRDTokenType::COMMENT - && ( ( pi.rawMode_ && handleRaw( token ) ) - || ( !pi.rawMode_ && handleProcessed( token ) ) ) ) { - return; - } - pi.pos_ ++; - if ( pi.pos_ >= pi.processLimit_ ) { - pi.rawMode_ = true; - } -} - -void T_SRDPreprocessorState::processNext( ) -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - assert( pi.input_ ); - assert( pi.pos_ < pi.input_->size( ) ); - processToken( (*pi.input_)[ pi.pos_ ] ); -} - -void T_SRDPreprocessorState::checkUnterminated( - T_SRDErrors& errors ) const -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - if ( !pi.rawMode_ ) { - return; - } - - auto const rss( pi.rawStack_.size( ) ); - for ( uint32_t i = 0 ; i < rss ; i ++ ) { - auto const& item( pi.rawStack_[ i ] ); - errors.add( "unterminated list" , item.location( ) ); - } -} - -void T_SRDPreprocessorState::terminate( ) -{ - // We need to store this so the current instance lives on until we exit - // the method. - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - auto se( pi.data_.pop( ) ); - assert( RP_SRDPreprocessorState( se ) == this ); - if ( pi.postExec_ ) { - try { - pi.postExec_( *this ); - } catch ( X_SRDErrors const& ) { - pi.data_.interrupt( C_TRY ); - } - } -} - -bool T_SRDPreprocessorState::handleRaw( - T_SRDToken& token ) -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - const auto tt( token.type( ) ); - - if ( tt == E_SRDTokenType::START ) { - T_SRDToken& top( pi.rawStack_[ - pi.rawStack_.add( T_SRDToken::List( ) ) ] ); - top.copyLocationOf( token ); - return false; - } - - const uint32_t ss( pi.rawStack_.size( ) ); - if ( tt == E_SRDTokenType::END ) { - if ( ss == 0 ) { - terminate( ); - return true; - } - - const uint32_t last( ss - 1 ); - T_SRDToken top( std::move( pi.rawStack_[ last ] ) ); - pi.rawStack_.remove( last ); - if ( last != 0 ) { - pi.rawStack_[ last - 1 ].list( ).add( std::move( top ) ); - } else { - pi.output_->add( std::move( top ) ); - } - return false; - } - - if ( ss != 0 ) { - pi.rawStack_[ ss - 1 ].list( ).add( std::move( token ) ); - } else { - pi.output_->add( std::move( token ) ); - } - return false; -} - -bool T_SRDPreprocessorState::handleProcessed( - T_SRDToken& token ) -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - const auto tt( token.type( ) ); - - // Lists that have already been processed - if ( tt == E_SRDTokenType::LIST ) { - T_SRDPreprocessorState& nState( - pi.data_.push( C_UNSPECIFIED , - NewShared< T_SRDList >( std::move( token.list( ) ) ) , - NewShared< T_SRDList >( ) , - &T_SRDPreprocessorState::handleEndOfList ) ); - nState.p< T_SRDPPStateImpl_ >( ).initialLocation_ = NewShared< T_SRDLocation >( token.location( ) ); - return false; - } - - // Start of unprocessed list - if ( tt == E_SRDTokenType::START ) { - T_SRDPreprocessorState& nState( pi.data_.push( ) ); - auto& npi( nState.p< T_SRDPPStateImpl_ >( ) ); - npi.postExec_ = &T_SRDPreprocessorState::handleEndOfList; - npi.initialLocation_ = NewShared< T_SRDLocation >( token.location( ) ); - return false; - } - - // End of unprocessed list - if ( tt == E_SRDTokenType::END ) { - terminate( ); - return true; - } - - // Variables and calls - if ( tt == E_SRDTokenType::VAR ) { - handleVariable( token ); - return false; - } - - // Macros, commands and words at the start of a list - if ( tt == E_SRDTokenType::WORD && pi.pos_ == 0 - && !pi.data_.topLevel( ) && pi.type_ == C_UNSPECIFIED - && checkCommandsAndMacros( token ) ) { - return false; - } - - // Otherwise simply copy the token - pi.output_->addNew( std::move( token ) ); - return false; -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorState::handleVariable( - T_SRDToken& token ) -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - auto const& s( pi.data_.scopes( ) ); - auto const& vn( token.stringValue( ) ); - RPC_SRDList var( s.get( false , vn ) ); - if ( var == nullptr ) { - try { - pi.data_.addError( token , "unknown variable" ); - } catch ( X_SRDErrors const& ) { - pi.data_.interrupt( C_TRY ); - } - } else if ( pi.type_ == C_UNSPECIFIED && pi.pos_ == 0 - && s.isBlessed( vn ) ) { - initFunctionCall( ( *var )[ 0 ].list( ) ); - } else { - pi.output_->addAll( *var ); - } -} - -bool T_SRDPreprocessorState::checkCommandsAndMacros( - T_SRDToken& token ) -{ - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - auto const& cfg( pi.data_.preprocessor( ).config( ) ); - RPC_SRDPreprocessorCommand cmd( cfg.command( token.stringValue( ) ) ); - if ( cmd != nullptr ) { - const auto pl( cmd->processArgs( ) ); - if ( pl != UINT32_MAX ) { - pi.processLimit_ = 1 + pl; - } - pi.postExec_ = [cmd]( T_SRDPreprocessorState& state ) { - cmd->execute( state ); - }; - return true; - } - - RPC_SRDList macro( pi.data_.scopes( ).get( true , token.stringValue( ) ) ); - if ( macro != nullptr ) { - initMacro( *macro ); - return true; - } - - if ( token.stringValue( )[ 0 ] == '-' ) { - try { - pi.data_.addError( token , "unknown command" ); - } catch ( X_SRDErrors const& ) { - pi.data_.interrupt( C_TRY ); - } - return true; - } - - return false; -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorState::initFunctionCall( - T_SRDList const& function ) -{ - assert( function.size( ) > 0 ); - assert( function[ 0 ].type( ) == E_SRDTokenType::LIST ); - - p< T_SRDPPStateImpl_ >( ).postExec_ = [&]( T_SRDPreprocessorState& state ) { - const uint32_t fSize( function.size( ) ); - T_SRDToken arguments( function[ 0 ] ); - SP_SRDList body( NewShared< T_SRDList >( fSize > 1 ? ( fSize - 1 ) : 1 ) ); - for ( uint32_t i = 1 ; i < fSize ; i ++ ) { - body->add( function[ i ] ); - } - - auto& sp( state.p< T_SRDPPStateImpl_ >( ) ); - auto& data( sp.data_ ); - auto const& args( arguments.list( ) ); - if ( !state.checkCallArguments( args ) ) { - return; - } - - data.pushCallLocation( sp.initialLocation_ ); - data.scopes( ).setupCallScope( args , *sp.output_ ); - data.push( C_CALL , body , NewShared< T_SRDList >( ) , - []( T_SRDPreprocessorState& ns ) { - auto& nsp( ns.p< T_SRDPPStateImpl_ >( ) ); - auto& data( nsp.data_ ); - data.scopes( ).exit( ); - - const auto callDepth( data.callRecursionDepth( ) ); - SP_SRDLocation initialLocation( data.popCallLocation( ) ); - auto& output( data.top( ).output( ) ); - auto& input( ns.output( ) ); - const auto is( input.size( ) ); - for ( size_t i = 0 ; i < is ; i ++ ) { - T_SRDToken token( std::move( input[ i ] ) ); - auto& loc( token.location( ) ); - if ( !loc.isChained( ) ) { - SP_SRDLocation gLoc( NewShared< T_SRDLocation >( loc ) ); - gLoc->chain( E_SRDLocationChaining::CALLED , callDepth , - initialLocation ); - loc.chain( E_SRDLocationChaining::GENERATED , gLoc ); - } - output.add( std::move( token ) ); - } - } ); - }; -} - -void T_SRDPreprocessorState::initMacro( - T_SRDList const& macro ) -{ - assert( macro.size( ) > 0 ); - assert( macro[ 0 ].type( ) == E_SRDTokenType::LIST ); - - auto& pi( p< T_SRDPPStateImpl_ >( ) ); - pi.rawMode_ = true; - pi.postExec_ = [&]( T_SRDPreprocessorState& state ) { - const uint32_t mSize( macro.size( ) ); - T_SRDToken arguments( macro[ 0 ] ); - SP_SRDList body( NewShared< T_SRDList >( - mSize > 1 ? ( mSize - 1 ) : 1 ) ); - for ( uint32_t i = 1 ; i < mSize ; i ++ ) { - body->add( macro[ i ] ); - } - - auto& sp( state.p< T_SRDPPStateImpl_ >( ) ); - auto& data( sp.data_ ); - auto const& args( arguments.list( ) ); - if ( !state.checkCallArguments( args ) ) { - return; - } - - SP_SRDLocation evalLocation( sp.initialLocation_ ); - data.pushCallLocation( sp.initialLocation_ ); - data.scopes( ).setupCallScope( args , *sp.output_ ); - data.push( C_CALL , body , NewShared< T_SRDList >( ) , - [evalLocation]( T_SRDPreprocessorState& ns ) { - // Process the macro's output - auto& nsp( ns.p< T_SRDPPStateImpl_ >( ) ); - auto& data( nsp.data_ ); - data.scopes( ).exit( ); - - const uint32_t depth( data.callRecursionDepth( ) ); - SP_SRDLocation callLocation( data.popCallLocation( ) ); - SP_SRDList updated( NewShared< T_SRDList >( nsp.output_->size( ) - ? nsp.output_->size( ) : 1 ) ); - auto& input( ns.output( ) ); - const auto is( input.size( ) ); - for ( size_t i = 0 ; i < is ; i ++ ) { - T_SRDToken token( std::move( input[ i ] ) ); - auto& loc( token.location( ) ); - SP_SRDLocation el( NewShared< T_SRDLocation >( *evalLocation ) ); - if ( loc.isChained( ) ) { - auto const& lc( loc.chaining( ) ); - el->chain( lc.circumstances , lc.location ); - } else { - SP_SRDLocation gen( NewShared< T_SRDLocation >( loc ) ); - gen->chain( E_SRDLocationChaining::CALLED , - depth , callLocation ); - el->chain( E_SRDLocationChaining::GENERATED , gen ); - } - loc.chain( E_SRDLocationChaining::EVALUATED , el ); - updated->add( std::move( token ) ); - } - - data.push( T_SRDPreprocessorState::C_UNSPECIFIED , - updated , data.top( ).outputPointer( ) ); - } ); - }; -} - -bool T_SRDPreprocessorState::checkCallArguments( - T_SRDList const& spec ) const -{ - auto const& pi( p< T_SRDPPStateImpl_ >( ) ); - const bool hasOptArgs( spec.size( ) > 0 - && spec[ spec.size( ) - 1 ].type( ) == E_SRDTokenType::LIST ); - const uint32_t reqArgs( spec.size( ) - ( hasOptArgs ? 1 : 0 ) ); - auto const& argVals( *pi.output_ ); - if ( argVals.size( ) < reqArgs ) { - p< T_SRDPPStateImpl_ >( ).data_.addError( - *pi.initialLocation_ , "not enough arguments" ); - return false; - } - if ( argVals.size( ) > reqArgs && !hasOptArgs ) { - p< T_SRDPPStateImpl_ >( ).data_.addError( - *pi.initialLocation_ , "too many arguments" ); - return false; - } - return true; -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorState::handleEndOfList( - T_SRDPreprocessorState& state ) -{ - auto& spi( state.p< T_SRDPPStateImpl_ >( ) ); - auto& output( *( spi.data_.top( ).p< T_SRDPPStateImpl_ >( ).output_ ) ); - uint32_t const pos( output.add( T_SRDToken::List( std::move( *spi.output_ ) ) ) ); - output[ pos ].location( std::move( *spi.initialLocation_ ) ); -} - - -/*= T_SRDPreprocessorScopes ==================================================*/ - -constexpr char T_SRDPreprocessorScopes::C_SET_; -constexpr char T_SRDPreprocessorScopes::C_BLESSED_; - -T_SRDPreprocessorScopes::T_SRDPreprocessorScopes( ) - : depth_( 0 ) -{ } - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorScopes::exit( ) -{ - assert( depth_ > 0 ); - - // Find all items for the current depth - const uint32_t size( itemDepth_.size( ) ); - const uint32_t nItems( ( [&]() { - uint32_t nItems( 0 ); - while ( size - nItems > 0 && itemDepth_[ size - nItems - 1 ] == depth_ ) { - nItems ++; - } - return nItems; - } )( ) ); - - // Remove items - for ( uint32_t i = 0 ; i < nItems ; i ++ ) { - const uint32_t ii( size - i - 1 ); - const uint32_t mainIndex( reverse_[ ii ] ); - const uint32_t chain( chain_[ ii ] ); - - // We're always removing from the end of the array, so removeSwap - // isn't needed. - if ( chain == T_HashIndex::INVALID_INDEX ) { - index_.remove( mainIndex ); - keys_.remove( mainIndex ); - indices_.remove( mainIndex ); - } else { - reverse_[ chain ] = mainIndex; - indices_[ mainIndex ] = chain; - } - - itemDepth_.remove( ii ); - chain_.remove( ii ); - reverse_.remove( ii ); - flags_.remove( ii ); - contents_.remove( ii ); - } - - depth_ --; -} - -void T_SRDPreprocessorScopes::clear( ) -{ - if ( depth_ == 0 ) { - index_.clear( ); - keys_.clear( ); - indices_.clear( ); - itemDepth_.clear( ); - chain_.clear( ); - reverse_.clear( ); - flags_.clear( ); - contents_.clear( ); - return; - } - - const uint32_t nEntries( keys_.size( ) ); - for ( uint32_t i = 0 ; i < nEntries ; i ++ ) { - const uint32_t idx( indices_[ i ] ); - if ( ( flags_[ idx ] & C_SET_ ) == 0 ) { - continue; - } - - if ( itemDepth_[ idx ] == depth_ ) { - flags_[ idx ] = 0; - contents_[ idx ] = NewShared< T_SRDList >( ); - } else { - addChained( i , idx , 0 , NewShared< T_SRDList >( ) ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorScopes::setupCallScope( - T_SRDList const& spec , - T_SRDList const& values , - uint32_t start ) -{ - const uint32_t nEntries( indices_.size( ) ); - enter( ); - - // Add parameters - const auto nSpec( spec.size( ) ); - for ( uint32_t i = 0 ; i < nSpec ; i ++ ) { - auto const& argSpec( spec[ i ] ); - - if ( argSpec.type( ) == E_SRDTokenType::WORD ) { - assert( i < values.size( ) ); - bool ok( set( false , argSpec.stringValue( ) , values , - i + start , i + start ) ); - assert( ok ); - continue; - } - - assert( argSpec.type( ) == E_SRDTokenType::LIST - && i == nSpec - 1 ); - - T_SRDList const& optArgs( argSpec.list( ) ); - const auto nOpt( optArgs.size( ) ); - for ( uint32_t j = 0 ; j < nOpt ; j ++ ) { - auto const& optArg( optArgs[ j ] ); - assert( optArg.type( ) == E_SRDTokenType::WORD ); - - bool ok( set( false , optArg.stringValue( ) , - values , i + j + start , - j == nOpt - 1 ? UINT32_MAX : i + j + start ) ); - assert( ok ); - } - } - - // Hide all variables from previous scopes - for ( uint32_t i = 0 ; i < nEntries ; i ++ ) { - if ( keys_[ i ].first ) { - continue; - } - - const uint32_t index( indices_[ i ] ); - if ( itemDepth_[ index ] == depth_ ) { - continue; - } - - const char flags( flags_[ index ] ); - if ( ( flags & C_SET_ ) == 0 || ( flags & C_BLESSED_ ) != 0 ) { - continue; - } - addChained( i , index , 0 , NewShared< T_SRDList >( ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -RPC_SRDList T_SRDPreprocessorScopes::get( - const bool macro , - T_String const& name ) const -{ - const uint32_t idx( find( macro , name ) ); - if ( idx == T_HashIndex::INVALID_INDEX ) { - return nullptr; - } - const uint32_t vIndex( indices_[ idx ] ); - if ( ( flags_[ vIndex ] & C_SET_ ) == 0 ) { - return nullptr; - } - return RPC_SRDList( contents_[ vIndex ] ); -} - -bool T_SRDPreprocessorScopes::canSet( - const bool macro , - T_String const& name ) const -{ - const uint32_t idx( find( macro , name ) ); - if ( idx == T_HashIndex::INVALID_INDEX ) { - return true; - } - const uint32_t vIndex( indices_[ idx ] ); - return ( itemDepth_[ vIndex ] != depth_ - || ( flags_[ vIndex ] & C_SET_ ) == 0 ); -} - -/*----------------------------------------------------------------------------*/ - -bool T_SRDPreprocessorScopes::set( - const bool macro , - T_String const& name , - T_SRDList const& value , - const uint32_t from , - const uint32_t to ) -{ - const uint32_t hash( ComputeHash( name ) ^ ( macro ? 0x55555555 : 0 ) ); - const uint32_t idx( find( hash , macro , name ) ); - - // If no entry exists, create a new one - if ( idx == T_HashIndex::INVALID_INDEX ) { - index_.add( hash ); - - const uint32_t mainIndex( keys_.size( ) ); - keys_.add( std::pair< bool , T_String >( macro , name ) ); - indices_.add( itemDepth_.size( ) ); - - itemDepth_.add( depth_ ); - chain_.add( T_HashIndex::INVALID_INDEX ); - reverse_.add( mainIndex ); - flags_.add( C_SET_ ); - contents_.add( NewShared< T_SRDList >( - value.copyRange( from , to ) ) ); - return true; - } - - const uint32_t previous( indices_[ idx ] ); - - // If there's an entry at the current depth, try to update it. - if ( itemDepth_[ previous ] == depth_ ) { - if ( ( flags_[ previous ] & C_SET_ ) != 0 ) { - return false; - } - flags_[ previous ] = C_SET_; - contents_[ previous ] = NewShared< T_SRDList >( - value.copyRange( from , to ) ); - return true; - } - - // Otherwise we need to chain it - addChained( idx , previous , C_SET_ , NewShared< T_SRDList >( - value.copyRange( from , to ) ) ); - return true; -} - -bool T_SRDPreprocessorScopes::unset( - const bool macro , - T_String const& name ) -{ - const uint32_t idx( find( macro , name ) ); - if ( idx == T_HashIndex::INVALID_INDEX ) { - return false; - } - const uint32_t vIndex( indices_[ idx ] ); - if ( ( flags_[ vIndex ] & C_SET_ ) == 0 ) { - return false; - } - if ( itemDepth_[ vIndex ] == depth_ ) { - if ( depth_ == 0 ) { - removeItem( idx ); - } else { - contents_[ vIndex ] = NewShared< T_SRDList >( ); - flags_[ vIndex ] = 0; - } - return true; - } - addChained( idx , vIndex , 0 , NewShared< T_SRDList >( ) ); - return true; -} - -/*----------------------------------------------------------------------------*/ - -bool T_SRDPreprocessorScopes::isBlessed( - T_String const& name ) const -{ - const uint32_t idx( find( false , name ) ); - if ( idx == T_HashIndex::INVALID_INDEX ) { - return false; - } - const uint32_t vIndex( indices_[ idx ] ); - return ( ( flags_[ vIndex ] & C_BLESSED_ ) != 0 ); -} - -bool T_SRDPreprocessorScopes::bless( - T_String const& name ) -{ - const uint32_t idx( find( false , name ) ); - if ( idx == T_HashIndex::INVALID_INDEX ) { - return false; - } - - const uint32_t vIndex( indices_[ idx ] ); - const char cFlags( flags_[ vIndex ] ); - if ( ( cFlags & C_SET_ ) == 0 || ( cFlags & C_BLESSED_ ) != 0 ) { - return false; - } - - if ( itemDepth_[ vIndex ] == depth_ ) { - flags_[ vIndex ] = cFlags | C_BLESSED_; - } else { - addChained( idx , vIndex , cFlags | C_BLESSED_ , NewShared< T_SRDList >( contents_[ vIndex ] ) ); - } - return true; -} - -/*----------------------------------------------------------------------------*/ - -T_Array< T_String > T_SRDPreprocessorScopes::list( - const bool macros ) const -{ - T_Array< T_String > result; - const uint32_t nEntries( keys_.size( ) ); - for ( uint32_t i = 0 ; i < nEntries ; i ++ ) { - auto const& k( keys_[ i ] ); - if ( k.first != macros ) { - continue; - } - if ( ( flags_[ indices_[ i ] ] & C_SET_ ) == 0 ) { - continue; - } - result.add( k.second ); - } - return result; -} - -/*----------------------------------------------------------------------------*/ - -uint32_t T_SRDPreprocessorScopes::find( - const bool macro , - T_String const& name ) const -{ - const uint32_t hash( ComputeHash( name ) ^ ( macro ? 0x55555555 : 0 ) ); - uint32_t idx = index_.first( hash ); - while ( idx != T_HashIndex::INVALID_INDEX ) { - auto const& key( keys_[ idx ] ); - if ( key.first == macro && key.second == name ) { - break; - } - idx = index_.next( idx ); - } - return idx; -} - -uint32_t T_SRDPreprocessorScopes::find( - const uint32_t hash , - const bool macro , - T_String const& name ) const -{ - uint32_t idx = index_.first( hash ); - while ( idx != T_HashIndex::INVALID_INDEX ) { - auto const& key( keys_[ idx ] ); - if ( key.first == macro && key.second == name ) { - break; - } - idx = index_.next( idx ); - } - return idx; -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorScopes::addChained( - const uint32_t index , - const uint32_t previous , - const char flags , - SP_SRDList&& contents ) -{ - const uint32_t newIndex( itemDepth_.size( ) ); - itemDepth_.add( depth_ ); - chain_.add( previous ); - reverse_.add( index ); - flags_.add( flags ); - contents_.add( std::move( contents ) ); - indices_[ index ] = newIndex; - reverse_[ previous ] = newIndex; -} - -void T_SRDPreprocessorScopes::removeItem( - const uint32_t index ) -{ - // We only ever do that at depth 0, so we don't have to worry about - // chaining (we still need to update the index for the element that - // gets swapped, though). - - assert( depth_ == 0 ); - assert( keys_.size( ) == itemDepth_.size( ) ); - - itemDepth_.removeSwap( index ); - flags_.removeSwap( index ); - chain_.removeSwap( index ); - reverse_.removeSwap( index ); - contents_.removeSwap( index ); - - keys_.removeSwap( index ); - indices_.removeSwap( index ); - index_.remove( index ); - - if ( index != indices_.size( ) ) { - reverse_[ index ] = index; - indices_[ index ] = index; - } -} - - -/*= T_SRDPPDataImpl_ =========================================================*/ - -namespace { -struct T_SRDPPDataImpl_ { - T_SRDPreprocessor& preprocessor; - - SP_SRDPreprocessorScopes scopes; - T_Array< RP_SRDErrors > errors; - - T_Array< SP_SRDPreprocessorState > stack; - T_Array< SP_SRDLocation > callStack; - T_Array< uint32_t > recursionDepths; - - T_SRDPPDataImpl_( - T_SRDPreprocessor& preprocessor , - T_SRDErrors& errors , - SP_SRDPreprocessorScopes scopes ) noexcept; - ~T_SRDPPDataImpl_( ); -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -inline T_SRDPPDataImpl_::T_SRDPPDataImpl_( - T_SRDPreprocessor& preprocessor , - T_SRDErrors& errors , - SP_SRDPreprocessorScopes scopes ) noexcept - : preprocessor( preprocessor ) , - scopes( std::move( scopes ) ) , - errors( 32 ) -{ - this->errors.add( &errors ); -} - -T_SRDPPDataImpl_::~T_SRDPPDataImpl_( ) -{ - const uint32_t nErrors( errors.size( ) ); - for ( uint32_t i = 1 ; i < nErrors ; i ++ ) { - delete errors[ i ]; - } - - try { - T_SRDErrors& elst( *errors[ 0 ] ); - const uint32_t ss( stack.size( ) ); - for ( uint32_t i = 1 ; i < ss ; i ++ ) { - T_SRDPreprocessorState & state( *stack[ i ] ); - if ( state.initialLocation( ) ) { - elst.add( "unterminated list" , *state.initialLocation( ) ); - } - state.checkUnterminated( elst ); - } - } catch ( X_SRDErrors const& ) { - // Just stop adding errors - } -} - - -/*= T_SRDPreprocessorData ====================================================*/ - -T_SRDPreprocessorData::T_SRDPreprocessorData( - T_SRDPreprocessor& preprocessor , - T_SRDErrors& errors , - SP_SRDPreprocessorScopes scopes ) - : A_PrivateImplementation( new T_SRDPPDataImpl_( - preprocessor , errors , std::move( scopes ) ) ) -{ - push( ); -} - -/*----------------------------------------------------------------------------*/ - -T_SRDPreprocessor& T_SRDPreprocessorData::preprocessor( ) const -{ - return p< T_SRDPPDataImpl_ >( ).preprocessor; -} - -T_SRDList& T_SRDPreprocessorData::output( ) const -{ - return p< T_SRDPPDataImpl_ >( ).stack[ 0 ]->output( ); -} - -T_SRDPreprocessorScopes& T_SRDPreprocessorData::scopes( ) -{ - return *( p< T_SRDPPDataImpl_ >( ).scopes ); -} - -T_SRDPreprocessorScopes const& T_SRDPreprocessorData::scopes( ) const -{ - return *( p< T_SRDPPDataImpl_ >( ).scopes ); -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorData::push( - SP_SRDPreprocessorState&& state ) -{ - p< T_SRDPPDataImpl_ >( ).stack.add( std::move( state ) ); -} - -T_SRDPreprocessorState& T_SRDPreprocessorData::top( ) const -{ - auto const& stack( p< T_SRDPPDataImpl_ >( ).stack ); - return *( stack[ stack.size( ) - 1 ] ); -} - -bool T_SRDPreprocessorData::topLevel( ) const -{ - return p< T_SRDPPDataImpl_ >( ).stack.size( ) == 1; -} - -inline SP_SRDLocation T_SRDPreprocessorData::callLocation( ) const noexcept -{ - auto const& cs( p< T_SRDPPDataImpl_ >( ).callStack ); - if ( cs.size( ) ) { - return cs[ cs.size( ) - 1 ]; - } - return SP_SRDLocation( ); -} - -SP_SRDPreprocessorState T_SRDPreprocessorData::pop( ) -{ - auto& stack( p< T_SRDPPDataImpl_ >( ).stack ); - const auto last( stack.size( ) - 1 ); - SP_SRDPreprocessorState state( stack[ last ] ); - stack.remove( last ); - return state; -} - -void T_SRDPreprocessorData::interrupt( - const T_SRDPreprocessorState::E_Type type ) -{ - assert( type != T_SRDPreprocessorState::C_UNSPECIFIED - && type != T_SRDPreprocessorState::C_INNER ); - - auto& stack( p< T_SRDPPDataImpl_ >( ).stack ); - const uint32_t ss( stack.size( ) ); - uint32_t i( 0 ); - while ( i < ss ) { - auto& toRemove( *( stack[ ss - i - 1 ] ) ); - i ++; - toRemove.setExiting( type ); - if ( toRemove.type( ) == type ) { - break; - } - } -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorData::pushCallLocation( - SP_SRDLocation const& location ) noexcept -{ - auto& pi( p< T_SRDPPDataImpl_ >( ) ); - const auto css( pi.callStack.size( ) ); - if ( css ) { - auto& next( pi.callStack[ css - 1 ] ); - auto depth( pi.recursionDepths[ css - 1 ] ); - SP_SRDLocation append( NewShared< T_SRDLocation >( *location ) ); - if ( next->line( ) == location->line( ) - && next->character( ) == location->character( ) - && next->source( ) == location->source( ) ) { - pi.recursionDepths.add( depth + 1 ); - if ( next->isChained( ) ) { - auto& nc( next->chaining( ) ); - append->chain( E_SRDLocationChaining::CALLED , nc.depth , - nc.location ); - } - } else { - append->chain( E_SRDLocationChaining::CALLED , depth , next ); - pi.recursionDepths.add( 1 ); - } - pi.callStack.add( std::move( append ) ); - } else { - pi.callStack.add( location ); - pi.recursionDepths.add( 1 ); - } -} - -SP_SRDLocation T_SRDPreprocessorData::popCallLocation( ) noexcept -{ - auto& pi( p< T_SRDPPDataImpl_ >( ) ); - const auto css( pi.callStack.size( ) ); - SP_SRDLocation location( pi.callStack[ css - 1 ] ); - pi.callStack.remove( css - 1 ); - pi.recursionDepths.remove( css - 1 ); - return location; -} - -uint32_t T_SRDPreprocessorData::callRecursionDepth( ) const noexcept -{ - auto& pi( p< T_SRDPPDataImpl_ >( ) ); - const auto css( pi.callStack.size( ) ); - assert( css > 0 ); - return pi.recursionDepths[ css - 1 ]; -} - -/*----------------------------------------------------------------------------*/ - -void T_SRDPreprocessorData::pushErrorContext( ) -{ - p< T_SRDPPDataImpl_ >( ).errors.add( new T_SRDErrors( ) ); -} - -RP_SRDErrors T_SRDPreprocessorData::popErrorContext( ) -{ - auto& errs( p< T_SRDPPDataImpl_ >( ).errors ); - const auto sz( errs.size( ) ); - assert( sz > 1 ); - - const RP_SRDErrors record( errs[ sz - 1 ] ); - errs.remove( sz - 1 ); - return record; -} - -T_SRDErrors& T_SRDPreprocessorData::errorContext( ) const -{ - auto const& errs( p< T_SRDPPDataImpl_ >( ).errors ); - return *( errs[ errs.size( ) - 1 ] ); -} - -void T_SRDPreprocessorData::addError( - T_SRDLocation const& location , - T_String const& text ) -{ - auto& pi( p< T_SRDPPDataImpl_ >( ) ); - auto& errs( pi.errors ); - const auto last( errs.size( ) - 1 ); - RP_SRDErrors errData( errs[ last ] ); - - const auto css( pi.callStack.size( ) ); - if ( css == 0 || location.isChained( ) ) { - errData->add( text , location ); - } else { - T_SRDLocation l( location ); - l.chain( E_SRDLocationChaining::CALLED , callRecursionDepth( ) , - pi.callStack[ css - 1 ] ); - errData->add( text , l ); - } -} - - -/*= T_SRDPreprocessor ========================================================*/ - -T_SRDPreprocessor::T_SRDPreprocessor( - T_SRDPreprocessorConfig const& config , - A_SRDReaderTarget& target , - SP_SRDPreprocessorScopes scopes ) - : config_( config ) , target_( target ) , scopes_( scopes ) -{ } - -void T_SRDPreprocessor::start( T_SRDErrors& errors ) -{ - if ( scopes_ ) { - data_ = NewOwned< T_SRDPreprocessorData >( *this , errors , scopes_ ); - } else { - data_ = NewOwned< T_SRDPreprocessorData >( *this , errors ); - } - outPos_ = 0; - outDepth_ = 0; - target_.start( errors ); -} - -void T_SRDPreprocessor::push( - T_SRDErrors& errors , - T_SRDToken&& token ) -{ - while ( !data_->topLevel( ) && data_->top( ).isExiting( ) ) { - data_->top( ).terminate( ); - } - - // Process the new token - if ( !data_->top( ).isExiting( ) ) { - data_->top( ).processToken( token ); - } - - // Try to process as much as possible from the stack - while ( 1 ) { - auto& top( data_->top( ) ); - if ( top.isExiting( ) ) { - if ( data_->topLevel( ) ) { - break; - } - top.terminate( ); - continue; - } - - if ( !top.hasInput( ) ) { - break; - } - if ( top.isFinished( ) ) { - top.terminate( ); - } else { - top.processNext( ); - } - } - - // Send output to the target - auto& outBuffer( data_->output( ) ); - const uint32_t bufSize( outBuffer.size( ) ); - assert( outPos_ <= bufSize ); - uint32_t remove = 0; - for ( uint32_t i = outPos_ ; i < bufSize ; i ++ ) { - auto& token( outBuffer[ i ] ); - const auto tt( token.type( ) ); - if ( tt == E_SRDTokenType::START ) { - outDepth_ ++; - - } else if ( tt == E_SRDTokenType::END ) { - assert( outDepth_ > 0 ); - outDepth_ --; - if ( outDepth_ == 0 ) { - for ( uint32_t j = 0 ; j <= i ; j ++ ) { - sendOutput( errors , outBuffer[ j ] ); - } - remove = i + 1; - outPos_ = i; - } - - } else if ( outDepth_ == 0 ) { - sendOutput( errors , token ); - remove ++; - } - } - outPos_ = bufSize; - if ( remove != 0 ) { - outBuffer = outBuffer.moveRange( remove , bufSize ); - outPos_ -= remove; - - target_.push( errors , T_SRDToken::Flush( ) ); - } -} - -void T_SRDPreprocessor::end( - T_SRDErrors& errors ) -{ - data_ = T_OwnPtr< T_SRDPreprocessorData >( ); - target_.end( errors ); -} - -void T_SRDPreprocessor::sendOutput( - T_SRDErrors& errors , - T_SRDToken& token ) -{ - if ( token.type( ) == E_SRDTokenType::LIST ) { - { - T_SRDToken lStart( T_SRDToken::ListStart( ) ); - lStart.copyLocationOf( token ); - target_.push( errors , std::move( lStart ) ); - } - { - auto& list( token.list( ) ); - const auto n( list.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - sendOutput( errors , list[ i ] ); - } - } - { - T_SRDToken lEnd( T_SRDToken::ListEnd( ) ); - lEnd.copyLocationOf( token ); - target_.push( errors , std::move( lEnd ) ); - } - - } else { - target_.push( errors , std::move( token ) ); - } -} - -/*----------------------------------------------------------------------------*/ - -bool T_SRDPreprocessor::isValidFunction( - T_SRDToken const& token ) -{ - if ( token.type( ) != E_SRDTokenType::LIST ) { - return false; - } - - auto const& list( token.list( ) ); - if ( list.size( ) == 0 ) { - return false; - } - - auto const& ft( list[ 0 ] ); - if ( ft.type( ) != E_SRDTokenType::LIST ) { - return false; - } - - auto const& pl( ft.list( ) ); - const auto n( pl.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto const& p( pl[ i ] ); - const auto tt( p.type( ) ); - - if ( tt == E_SRDTokenType::WORD ) { - // Check for duplicate names - auto const& pn( p.stringValue( ) ); - for ( uint32_t j = 0 ; j < i ; j ++ ) { - if ( pl[ j ].stringValue( ) == pn ) { - return false; - } - } - continue; - - } else if ( tt != E_SRDTokenType::LIST ) { - return false; - } - - // Must be the last entry - if ( i != n - 1 ) { - return false; - } - - auto const& opl( p.list( ) ); - const auto no( opl.size( ) ); - if ( no == 0 ) { - return false; - } - for ( uint32_t j = 0 ; j < no ; j ++ ) { - auto const& op( opl[ j ] ); - if ( op.type( ) != E_SRDTokenType::WORD ) { - return false; - } - - auto const& opn( op.stringValue( ) ); - // Check for duplicates in main list - for ( uint32_t k = 0 ; k < i ; k ++ ) { - if ( pl[ k ].stringValue( ) == opn ) { - return false; - } - } - // Check for duplicates in optional args - for ( uint32_t k = 0 ; k < j ; k ++ ) { - if ( opl[ k ].stringValue( ) == opn ) { - return false; - } - } - } - } - - return true; -} diff --git a/src/SRDText.cc b/src/SRDText.cc index d703ea4..e8ac8bb 100644 --- a/src/SRDText.cc +++ b/src/SRDText.cc @@ -3,8 +3,8 @@ /******************************************************************************/ -#include -using namespace lw; +#include +using namespace ebcl; /*= T_SRDLexerPrivate_ =======================================================*/ @@ -787,7 +787,7 @@ inline void T_SRDLexerPrivate_::processEnd( ) case E_State_::COMMENT_ML: pushComment( ); - + // fall through case E_State_::COMMENT_ML_START: error( "unterminated multi-line comment" ); break; @@ -798,7 +798,7 @@ inline void T_SRDLexerPrivate_::processEnd( ) case E_State_::NB_FRAC_PART_M: error( "fractional part expected" ); - + // fall through case E_State_::NB_FRAC_PART: case E_State_::NB_EXP: pushFloat( ); @@ -814,7 +814,7 @@ inline void T_SRDLexerPrivate_::processEnd( ) error( "incomplete word" ); stringBuffer_.clear( ); stringBuffer_ << "invalid"; - + // fall through case E_State_::WORD: pushWord( ); break; @@ -899,7 +899,7 @@ void T_SRDTextReader::read( T_String const& name , A_InputStream& input ) /*= TEXT LEXING HELPERS ======================================================*/ -T_SRDList lw::SRDFromText( T_String const& name , T_String const& string , bool structured ) +T_SRDList ebcl::SRDFromText( T_String const& name , T_String const& string , bool structured ) { T_SRDMemoryTarget mt( structured ); T_SRDErrors errors; @@ -919,7 +919,7 @@ T_SRDList lw::SRDFromText( T_String const& name , T_String const& string , bool return mt.list( ); } -T_SRDList lw::SRDFromText( T_String const& name , char const* string , bool structured ) +T_SRDList ebcl::SRDFromText( T_String const& name , char const* string , bool structured ) { T_SRDMemoryTarget mt( structured ); T_SRDErrors errors; diff --git a/src/TemplateInstantiation.cc b/src/TemplateInstantiation.cc index 9a5622b..338bdaa 100644 --- a/src/TemplateInstantiation.cc +++ b/src/TemplateInstantiation.cc @@ -5,6 +5,8 @@ #include #include #include +#include +#include namespace ebcl { @@ -17,6 +19,8 @@ template struct T_Comparator< uint32_t >; template class T_Array< uint32_t >; template class T_Array< bool >; template class T_Array< T_String >; +template class T_Array< T_SRDInputItem >; +template class T_Array< T_SRDToken >; /*----------------------------------------------------------------------------*/ diff --git a/src/TextFileLogger.cc b/src/TextFileLogger.cc deleted file mode 100644 index ce7f509..0000000 --- a/src/TextFileLogger.cc +++ /dev/null @@ -1,159 +0,0 @@ -/******************************************************************************/ -/* LOGGING SYSTEM - BUILT-IN LOGGERS - TEXT FILE LOGGER ***********************/ -/******************************************************************************/ - -#include -#include -using namespace lw; - - -namespace { - - -char const* const V_Name_ = "text-file"; -inline T_String Name_( ) { return T_String::Pooled( V_Name_ ); } - -bool TFLCPath_( T_SRDParserData const& data ) -{ - auto const& ptok( (*data.input)[ 1 ] ); - T_VFSPath path( ptok.stringValue( ) ); - path = path.normalize( ); - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - data.errors.add( "invalid path" , ptok ); - } else { - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - ( dynamic_cast< T_TextFileLogWriterCfg* >( lconf ) )->setPath( std::move( path ) ); - } - return true; -} - -bool TFLCAppend_( T_SRDParserData const& data ) -{ - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - ( dynamic_cast< T_TextFileLogWriterCfg* >( lconf ) )->setAppend( true ); - return true; -} - -bool TFLCTruncate_( T_SRDParserData const& data ) -{ - auto lconf( data.targetData->value< RP_LogWriterConfiguration >( ) ); - ( dynamic_cast< T_TextFileLogWriterCfg* >( lconf ) )->setAppend( false ); - return true; -} - -} - - -/*= T_TextFileLogWriterFactory ==================================================*/ - -T_TextFileLogWriterFactory::T_TextFileLogWriterFactory( T_VFS& vfs ) - : A_LogWriterFactory( Name_( ) ) , vfs_( vfs ) -{ } - -RP_LogWriterConfiguration T_TextFileLogWriterFactory::createConfiguration( T_String const& name ) const -{ - RP_LogWriterConfiguration p( new T_TextFileLogWriterCfg( ) ); - p->setName( name ); - return p; -} - -OP_LogWriter T_TextFileLogWriterFactory::createLogWriter( OP_LogWriterConfiguration&& configuration ) const -{ - T_TextFileLogWriter* p( new T_TextFileLogWriter( std::move( configuration ) , vfs_ ) ); - return OwnRawPointer( p ); -} - -void T_TextFileLogWriterFactory::initializeSyntax( T_SRDParserDefs& , T_SRDContext& main ) const -{ - using namespace lw::SRD; - main << ( Rule( ) << "file" << Text( ) << TFLCPath_ ); - main << ( Rule( ) << "append" << TFLCAppend_ ); - main << ( Rule( ) << "truncate" << TFLCTruncate_ ); -} - - -/*= T_TextFileLogWriterCfg ======================================================*/ - -T_TextFileLogWriterCfg::T_TextFileLogWriterCfg( ) - : T_LogWriterConfiguration( Name_( ) ) -{ } - -T_TextFileLogWriterCfg::T_TextFileLogWriterCfg( T_TextFileLogWriterCfg const& source ) - : T_LogWriterConfiguration( source ) , path_( source.path_ ) , - append_( source.append_ ) -{ } - -OP_LogWriterConfiguration T_TextFileLogWriterCfg::clone( ) -{ - T_TextFileLogWriterCfg* ptr( new T_TextFileLogWriterCfg( *this ) ); - return OwnRawPointer( ptr ); -} - -void T_TextFileLogWriterCfg::check( T_SRDErrors& errors , T_SRDList const& input ) -{ - T_LogWriterConfiguration::check( errors , input ); - if ( path_.type( ) == E_VFSPathType::UNKNOWN || path_.elements( ) == 0 ) { - errors.add( "no file selected" , input[ 0 ] ); - } -} - - -/*= T_TextFileLogWriter =========================================================*/ - -T_TextFileLogWriter::T_TextFileLogWriter( OP_LogWriterConfiguration&& configuration , T_VFS& vfs ) - : A_LogWriter( std::move( configuration ) ) , vfs_( vfs ) -{ } - -void T_TextFileLogWriter::log( T_LogTimestamp const& timestamp , - E_LogLevel level , T_LogPath const& path , - T_LogStringData const& data , uint32_t size ) -{ - using namespace std::chrono; - - char timeBuffer[ 128 ]; - std::time_t tst( T_LogTimestamp::clock::to_time_t( timestamp ) ); - std::strftime( timeBuffer , 128 , "%Y-%m-%d %H:%M:%S" , std::gmtime( &tst ) ); - const auto ms( ( duration_cast< milliseconds >( timestamp - T_LogTimestamp( ) ) ).count( ) % 1000 ); - - T_StringBuilder sb; - - sb << timeBuffer << '.'; - if ( ms < 100 ) { - sb << '0'; - if ( ms < 10 ) { - sb << '0'; - } - } - sb << ms << ' ' << path.toString( ) << " - " << level << ": "; - sb.append( &( (*data) [ 0 ] ) , size ); - sb << '\n'; - - auto const& cfg( configuration< T_TextFileLogWriterCfg >( ) ); - auto const& p( cfg.path( ) ); - if ( !file_ ) { - vfs_.mkdir( p.parent( ) ); - file_ = vfs_.file( p , cfg.append( ) ? E_FileMode::READ_WRITE : E_FileMode::OVERWRITE ); - if ( !file_ ) { - disable( ); - return; - } - - try { - file_->open( ); - } catch ( X_StreamError const& ) { - disable( ); - file_.clear( ); - return; - } - } - - try { - file_->position( 0 , true ); - file_->write( sb.data( ) , sb.size( ) ); - file_->flush( ); - } catch ( X_StreamError ) { - disable( ); - file_.clear( ); - return; - } -} diff --git a/src/VFS.cc b/src/VFS.cc deleted file mode 100644 index 26619b2..0000000 --- a/src/VFS.cc +++ /dev/null @@ -1,930 +0,0 @@ -/******************************************************************************/ -/* VIRTUAL FILE SYSTEM ********************************************************/ -/******************************************************************************/ - -#include -#ifndef _WIN32 -# include -# include -# include -#endif -using namespace lw; - - -/*= VARIOUS INTERNALS ========================================================*/ - -namespace { - -bool MkDir_( T_String const& path ) -{ - const auto chars( path.toOSString( ) ); -#ifdef _WIN32 - return CreateDirectoryW( ( wchar_t const* ) &chars[ 0 ] , nullptr ); -#else - return mkdir( ( char const* ) &chars[ 0 ] , 0755 ) == 0; -#endif -} - -E_VFSEntryType TypeOfPath_( T_String const& path ) -{ - const auto chars( path.toOSString( ) ); - -#ifdef _WIN32 - - uint32_t fa( GetFileAttributesW( (wchar_t const*) & chars[ 0 ] ) ); - if ( fa == INVALID_FILE_ATTRIBUTES ) { - return E_VFSEntryType::NONE; - } else if ( ( fa & FILE_ATTRIBUTE_DIRECTORY ) != 0 ) { - return E_VFSEntryType::DIRECTORY; - } else if ( ( fa & FILE_ATTRIBUTE_NORMAL ) != 0 ) { - return E_VFSEntryType::FILE; - } else { - return E_VFSEntryType::OTHER; - } - -#else - - struct stat fa; - if ( stat( ( char const* ) &chars[ 0 ] , &fa ) ) { - return E_VFSEntryType::NONE; - } - - const auto masked( fa.st_mode & S_IFMT ); - switch ( masked ) { - case S_IFREG: - return E_VFSEntryType::FILE; - - case S_IFDIR: - return E_VFSEntryType::DIRECTORY; - - default: - return E_VFSEntryType::OTHER; - } - -#endif -} - -} // namespace - - -/*= T_DirLister_ =============================================================*/ - -namespace { - -class T_DirLister_ -{ - private: - T_Buffer< char > path_; -#ifdef _WIN32 - HANDLE handle_; - WIN32_FIND_DATAW output_; -#else - DIR* dir_; - struct dirent* output_; -#endif - - public: - explicit T_DirLister_( T_Buffer< char > path ); - ~T_DirLister_( ); - - bool start( ); - void next( ); - bool hasValue( ) const; - T_String getName( ) const; -}; - - -} // namespace - -/*----------------------------------------------------------------------------*/ - -inline T_DirLister_::T_DirLister_( T_Buffer< char > path ) - : path_( std::move( path ) ) -{ -#ifdef _WIN32 -# error "Not implemented" -#else - dir_ = nullptr; - output_ = nullptr; -#endif -} - -T_DirLister_::~T_DirLister_( ) -{ -#ifdef _WIN32 -# error "Not implemented" -#else - if ( dir_ != nullptr ) { - closedir( dir_ ); - } -#endif -} - -inline bool T_DirLister_::start( ) -{ -#ifdef _WIN32 -# error "Not implemented" -#else - dir_ = opendir( &path_[ 0 ] ); - if ( dir_ == nullptr ) { - return false; - } - output_ = readdir( dir_ ); - return true; -#endif -} - -inline void T_DirLister_::next( ) -{ -#ifdef _WIN32 -# error "Not implemented" -#else - output_ = readdir( dir_ ); -#endif -} - -inline bool T_DirLister_::hasValue( ) const -{ -#ifdef _WIN32 -# error "Not implemented" -#else - return output_ != nullptr; -#endif -} - -inline T_String T_DirLister_::getName( ) const -{ -#ifdef _WIN32 -# error "Not implemented" -#else - return T_String( output_->d_name , strlen( output_->d_name ) ); -#endif -} - - -/*= T_VFSPath ================================================================*/ - -T_VFSPath::T_VFSPath( E_VFSPathType type ) - : type_( type ) , elements_( 16 ) -{ } - - -T_VFSPath::T_VFSPath( T_String const& path ) - : T_VFSPath( ) -{ - extractPath( path ); -} - -/*----------------------------------------------------------------------------*/ - -T_VFSPath::T_VFSPath( T_VFSPath const& parent , T_VFSPath const& child ) - : T_VFSPath( parent.type_ ) -{ - if ( child.type( ) == E_VFSPathType::UNKNOWN ) { - type_ = E_VFSPathType::UNKNOWN; - } - if ( type_ == E_VFSPathType::UNKNOWN || child.type( ) == E_VFSPathType::UNKNOWN ) { - return; - } - - if ( child.type_ == E_VFSPathType::INVALID ) { - type_ = E_VFSPathType::INVALID; - } - elements_.ensureCapacity( parent.elements( ) + child.elements( ) ); - elements_.addAll( parent.elements_ ); - elements_.addAll( child.elements_ ); -} - -/*----------------------------------------------------------------------------*/ - -T_VFSPath::T_VFSPath( T_VFSPath const& other ) - : type_( other.type_ ) , elements_( other.elements_ ) -{ } - -T_VFSPath::T_VFSPath( T_VFSPath&& other ) noexcept - : T_VFSPath( ) -{ - swap( *this , other ); -} - -/*----------------------------------------------------------------------------*/ - -T_VFSPath& T_VFSPath::operator= ( T_VFSPath const& other ) -{ - type_ = other.type_; - elements_ = other.elements_; - return *this; -} - -T_VFSPath& T_VFSPath::operator= ( T_VFSPath&& other ) noexcept -{ - swap( *this , other ); - return *this; -} - -/*----------------------------------------------------------------------------*/ - -T_VFSPath::operator T_String ( ) const -{ - T_StringBuilder sb; - if ( type_ == E_VFSPathType::ABSOLUTE ) { - sb << '/'; - } - - const auto n( elements_.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - if ( i > 0 ) { - sb << '/'; - } - sb << elements_[ i ]; - } - - return T_String( std::move( sb ) ); -} - -/*----------------------------------------------------------------------------*/ - -void lw::swap( T_VFSPath& lhs , T_VFSPath& rhs ) noexcept -{ - using std::swap; - swap( lhs.type_ , rhs.type_ ); - swap( lhs.elements_ , rhs.elements_ ); -} - -/*----------------------------------------------------------------------------*/ - -T_VFSPath T_VFSPath::normalize( ) const -{ - T_VFSPath normed; - if ( type_ == E_VFSPathType::UNKNOWN || type_ == E_VFSPathType::INVALID ) { - return normed; - } - - normed.type_ = type_; - const auto absolute( type_ == E_VFSPathType::ABSOLUTE ); - const auto n( elements_.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto const& e( elements_[ i ] ); - - // Simply remove .'s - if ( e == "." ) { - continue; - } - - if ( e == ".." ) { - auto const te( normed.elements( ) ); - - // Remove ..'s at the start of an absolute path - if ( te == 0 && absolute ) { - continue; - } - - // Use ..'s to remove stuff like "dir/../wat/../wut/.." - if ( te != 0 && normed.elements_[ te - 1 ] != ".." ) { - normed.elements_.remove( te - 1 ); - continue; - } - } - normed.elements_.add( e ); - } - - if ( normed.elements( ) == 0 && normed.type( ) == E_VFSPathType::RELATIVE ) { - normed.elements_.add( T_String::Pooled( "." ) ); - } - - return normed; -} - -/*----------------------------------------------------------------------------*/ - -T_VFSPath T_VFSPath::parent( ) const -{ - if ( type_ == E_VFSPathType::UNKNOWN || type_ == E_VFSPathType::INVALID - || elements_.size( ) == 0 ) { - return *this; - } - - if ( type_ == E_VFSPathType::RELATIVE && elements_.size( ) == 1 ) { - T_VFSPath p( E_VFSPathType::RELATIVE ); - p.elements_.add( T_String::Pooled( "." ) ); - return p; - } - - T_VFSPath p( *this ); - p.elements_.remove( elements_.size( ) - 1 ); - return p; -} - -/*----------------------------------------------------------------------------*/ - -bool T_VFSPath::operator== ( T_VFSPath const& other ) const -{ - if ( this == &other ) { - return true; - } - - const auto n( elements( ) ); - if ( type_ != other.type_ || n != other.elements( ) ) { - return false; - } - - for ( uint32_t i = 0 ; i < n ; i ++ ) { - if ( elements_[ i ] != other[ i ] ) { - return false; - } - } - - return true; -} - -/*----------------------------------------------------------------------------*/ - -void T_VFSPath::extractPath( T_String const& path ) -{ - // Extract the path's elements - T_StringIterator it( path ); - bool elementStarted( false ) , absolute( false ) , invalid( false ); - uint32_t startIndex , index( 0 ); - while ( !it.atEnd( ) ) { - T_Character c( it ); - - if ( c == '/' ) { - if ( elementStarted ) { - elements_.add( path.range( startIndex , it.index( ) - 1 ) ); - elementStarted = false; - } - if ( it.index( ) == 0 ) { - absolute = true; - } - } else { - if ( !( c.isNumeric( ) || c.isLowercase( ) - || c == '-' || c == '_' || c == '.' ) ) { - invalid = true; - } - if ( !elementStarted ) { - elementStarted = true; - startIndex = it.index( ); - } - } - - it.next( ); - index ++; - } - - if ( elementStarted ) { - elements_.add( path.substr( startIndex ) ); - } - - // Only "." and ".." should start with a dot - if ( !invalid ) { - const auto n( elements_.size( ) ); - for ( uint32_t i = 0 ; i < n && !invalid ; i ++ ) { - T_String const& s( elements_[ i ] ); - if ( s[ 0 ] == '.' ) { - invalid = ( s != "." && s != ".." ); - } - } - } - - // Set the type - if ( invalid ) { - type_ = E_VFSPathType::INVALID; - } else if ( absolute ) { - type_ = E_VFSPathType::ABSOLUTE; - } else if ( elements_.size( ) == 0 ) { - type_ = E_VFSPathType::UNKNOWN; - } else { - type_ = E_VFSPathType::RELATIVE; - } -} - -/*----------------------------------------------------------------------------*/ - -M_DEFINE_HASH( T_VFSPath ) -{ - uint32_t hash( uint32_t( item.type( ) ) << 16 ); - const auto n( item.elements( ) ); - hash ^= n; - for ( uint32_t i = 0 ; i < n ; i ++ ) { - hash = ( hash << 11 ) | ( hash >> 21 ); - hash ^= ComputeHash( item[ i ] ); - } - return hash; -} - -/*= A_VFSDriver ==============================================================*/ - -bool A_VFSDriver::init( ) -{ - return true; -} - -void A_VFSDriver::shutdown( ) -{ } - -OP_File A_VFSDriver::file( T_VFSPath const& ) -{ - return OP_File( ); -} - - -/*= T_VFSFilesystemDriver ====================================================*/ - -#ifdef _WIN32 -# define C_SEPARATOR_ '\\' -#else -# define C_SEPARATOR_ '/' -#endif - -T_VFSFilesystemDriver::T_VFSFilesystemDriver( T_String root ) - : root_( root ) -{ } - -/*----------------------------------------------------------------------------*/ - -bool T_VFSFilesystemDriver::init( ) -{ - const auto path( root_.toOSString( ) ); - -#ifdef _WIN32 - - uint32_t fa( GetFileAttributesW( (wchar_t const*) & path[ 0 ] ) ); - return fa != INVALID_FILE_ATTRIBUTES && ( fa & FILE_ATTRIBUTE_DIRECTORY ) != 0; - -#else - - struct stat fa; - if ( stat( ( char const* ) &path[ 0 ] , &fa ) ) { - return false; - } - return ( fa.st_mode & S_IFMT ) == S_IFDIR; - -#endif -} - -/*----------------------------------------------------------------------------*/ - -E_VFSEntryType T_VFSFilesystemDriver::typeOf( T_VFSPath const& path ) -{ - return TypeOfPath_( getFullPath( path ) ); -} - -bool T_VFSFilesystemDriver::list( T_VFSPath const& path , T_Array< T_VFSPath >& values , T_HashIndex& index ) -{ - T_DirLister_ dl( getOSPath( path ) ); - if ( !dl.start( ) ) { - return false; - } - while ( dl.hasValue( ) ) { - const auto v( dl.getName( ) ); - dl.next( ); - if ( v == "." || v == ".." ) { - continue; - } - - const T_VFSPath entry( v ); - if ( entry.type( ) == E_VFSPathType::INVALID ) { - continue; - } - - const uint32_t hash( ComputeHash( entry ) ); - uint32_t idx( index.first( hash ) ); - while ( idx != T_HashIndex::INVALID_INDEX ) { - if ( values[ idx ] == entry ) { - break; - } - idx = index.next( idx ); - } - if ( idx == T_HashIndex::INVALID_INDEX ) { - index.add( hash ); - values.add( entry ); - } - } - return true; -} - -OP_InputStream T_VFSFilesystemDriver::read( T_VFSPath const& path ) -{ - if ( typeOf( path ) != E_VFSEntryType::FILE ) { - return OP_InputStream( ); - } else { - auto f( file( path ) ); - if ( f ) { - return NewOwned< T_FileInputStream >( std::move( f ) ); - } else { - return OP_InputStream( ); - } - } -} - -OP_File T_VFSFilesystemDriver::file( T_VFSPath const& path ) -{ - if ( typeOf( path ) != E_VFSEntryType::FILE ) { - return OP_File( ); - } - return NewOwned< T_File >( getFullPath( path ) , E_FileMode::READ_ONLY ); -} - -/*----------------------------------------------------------------------------*/ - -T_String T_VFSFilesystemDriver::getFullPath( T_VFSPath const& path ) const -{ - T_StringBuilder sb( root_ ); - const auto n( path.elements( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - sb << C_SEPARATOR_ << path[ i ]; - } - return T_String( std::move( sb ) ); -} - -inline T_Buffer< char > T_VFSFilesystemDriver::getOSPath( T_VFSPath const& path ) const -{ - return getFullPath( path ).toOSString( ); -} - - -/*= T_VFSUserDirectory_ ======================================================*/ - -namespace { - -class T_VFSUserDirectory_ : public T_VFSFilesystemDriver -{ - public: - explicit T_VFSUserDirectory_( T_String const& base ); - - bool init( ) override; - - OP_File file( T_VFSPath const& path ) override; - OP_File file( T_VFSPath const& path , E_FileMode mode ); - OP_OutputStream write( T_VFSPath const& path ); - bool mkdir( T_VFSPath const& path ) const; - bool rmdir( T_VFSPath const& path ) const; - bool rm( T_VFSPath const& path ) const; - bool move( T_VFSPath const& from , T_VFSPath const& to ) const; -}; - - -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_VFSUserDirectory_::T_VFSUserDirectory_( T_String const& base ) - : T_VFSFilesystemDriver( base ) -{ } - -bool T_VFSUserDirectory_::init( ) -{ - if ( T_VFSFilesystemDriver::init( ) ) { - return true; - } - - // Try creating the user directory - T_String const& r( root( ) ); - int32_t nextSep( r.find( C_SEPARATOR_ ) ); - while ( 1 ) { - const T_String p( nextSep == -1 ? r : r.substr( 0 , nextSep ) ); - if ( p ) { - const auto t( TypeOfPath_( p ) ); - if ( ( t != E_VFSEntryType::DIRECTORY && t != E_VFSEntryType::NONE ) - || ( t == E_VFSEntryType::NONE && !MkDir_( p ) ) ) { - return false; - } - } - if ( nextSep == -1 ) { - break; - } else { - nextSep = r.find( C_SEPARATOR_ , nextSep + 1 ); - } - } - - return true; -} - -/*----------------------------------------------------------------------------*/ - -OP_File T_VFSUserDirectory_::file( T_VFSPath const& path ) -{ - return T_VFSFilesystemDriver::file( path ); -} - -OP_File T_VFSUserDirectory_::file( T_VFSPath const& path , E_FileMode mode ) -{ - if ( mode == E_FileMode::READ_ONLY ) { - return file( path ); - } - - const auto fp( getFullPath( path ) ); - const auto ft( TypeOfPath_( fp ) ); - if ( ft != E_VFSEntryType::FILE && ft != E_VFSEntryType::NONE ) { - return OP_File( ); - } - return NewOwned< T_File >( fp , mode ); -} - -/*----------------------------------------------------------------------------*/ - -OP_OutputStream T_VFSUserDirectory_::write( T_VFSPath const& path ) -{ - auto f( file( path , E_FileMode::OVERWRITE ) ); - if ( f ) { - return NewOwned< T_FileOutputStream >( std::move( f ) ); - } else { - return OP_OutputStream( ); - } -} - -/*----------------------------------------------------------------------------*/ - -bool T_VFSUserDirectory_::mkdir( T_VFSPath const& path ) const -{ - T_StringBuilder sb( root( ) ); - const auto n( path.elements( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - sb << C_SEPARATOR_ << path[ i ]; - if ( !MkDir_( sb ) ) { - return false; - } - } - return true; -} - -bool T_VFSUserDirectory_::rmdir( T_VFSPath const& path ) const -{ - const auto chars( getOSPath( path ) ); -#ifdef _WIN32 - return RemoveDirectoryW( ( wchar_t const* ) &chars[ 0 ] ); -#else - return ::rmdir( ( char const* ) &chars[ 0 ] ) == 0; -#endif -} - -bool T_VFSUserDirectory_::rm( T_VFSPath const& path ) const -{ - const auto chars( getOSPath( path ) ); -#ifdef _WIN32 - return DeleteFileW( ( wchar_t const* ) &chars[ 0 ] ); -#else - return unlink( ( char const* ) &chars[ 0 ] ) == 0; -#endif -} - -bool T_VFSUserDirectory_::move( T_VFSPath const& from , T_VFSPath const& to ) const -{ - const auto charsFrom( getOSPath( from ) ); - const auto charsTo( getOSPath( to ) ); -#ifdef _WIN32 - return MoveFileW( ( wchar_t const* ) &charsFrom[ 0 ] , - ( wchar_t const* ) &charsTo[ 0 ] ); -#else - return rename( ( char const* ) &charsFrom[ 0 ] , - ( char const* ) &charsTo[ 0 ] ) == 0; -#endif -} - - -/*= T_VFSPrivate_ ============================================================*/ - -namespace { -struct T_VFSPrivate_ -{ - T_RegisteredItem::SP_Unregister unregisterFunction_{ - NewShared< T_RegisteredItem::F_Unregister >( - [this]( void* data ) { - auto const n( drivers_.size( ) ); - for ( uint32_t i = 0 ; i < n ; i ++ ) { - auto& p( drivers_[ i ] ); - if ( p.get( ) == data ) { - p->shutdown( ); - drivers_.removeSwap( i ); - break; - } - } - } - ) }; - OP_VFSFilesystemDriver userDir_; - T_Array< OP_VFSDriver > drivers_{ 16 }; - - static T_String findUserDir( ); - void initUserDir( T_String const& dir ); -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_String T_VFSPrivate_::findUserDir( ) -{ -#ifdef _WIN32 -# error "Not implemented!" -#else - T_String base; - char const* const lwHome( getenv( "LWHOME" ) ); - if ( lwHome == nullptr ) { - char const* const userHome( getenv( "HOME" ) ); - if ( userHome == nullptr ) { - throw X_VFSInitialisationFailure( ); - } else { - T_StringBuilder sb( userHome ); - sb << "/.local/share/LegacyWorlds"; - base = std::move( sb ); - } - } else { - base = T_String( lwHome , strlen( lwHome ) ); - } - return base; -#endif -} - -void T_VFSPrivate_::initUserDir( T_String const& dir ) -{ - assert( !userDir_ ); - userDir_ = NewOwned< T_VFSUserDirectory_ >( dir ); - if ( !userDir_->init( ) ) { - throw X_VFSInitialisationFailure( ); - } -} - - -/*= T_VFS ====================================================================*/ - -T_VFS::T_VFS( ) - : A_PrivateImplementation( new T_VFSPrivate_( ) ) -{ - p< T_VFSPrivate_ >( ).initUserDir( T_VFSPrivate_::findUserDir( ) ); -} - -T_VFS::T_VFS( T_String const& userDir ) - : A_PrivateImplementation( new T_VFSPrivate_( ) ) -{ - p< T_VFSPrivate_ >( ).initUserDir( userDir ); -} - -T_RegisteredItem T_VFS::addDriver( OP_VFSDriver&& driver ) -{ - assert( driver ); - const bool ok( driver->init( ) ); - if ( ok ) { - auto& pi( p< T_VFSPrivate_ >( ) ); - void* const ptr( driver.get( ) ); - pi.drivers_.add( std::move( driver ) ); - return T_RegisteredItem( pi.unregisterFunction_ , ptr ); - } - return T_RegisteredItem( ); -} - -/*----------------------------------------------------------------------------*/ - -E_VFSEntryType T_VFS::typeOf( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return E_VFSEntryType::NONE; - } - - auto& pi( p< T_VFSPrivate_ >( ) ); - const auto np( path.normalize( ) ); - E_VFSEntryType rv( pi.userDir_->typeOf( np ) ); - const auto nd( pi.drivers_.size( ) ); - for ( uint32_t i = nd ; i != 0 && rv == E_VFSEntryType::NONE ; i -- ) { - rv = pi.drivers_[ i - 1 ]->typeOf( np ); - } - - return rv; -} - -bool T_VFS::list( T_VFSPath const& path , T_Array< T_VFSPath >& output ) const -{ - output.clear( ); - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return false; - } - - const auto np( path.normalize( ) ); - auto& pi( p< T_VFSPrivate_ >( ) ); - T_HashIndex index( 1024 , 256 , 256 ); - bool rv( pi.userDir_->list( np , output , index ) ); - const auto nd( pi.drivers_.size( ) ); - for ( uint32_t i = nd ; i != 0 ; i -- ) { - rv = pi.drivers_[ i - 1 ]->list( np , output , index ) || rv; - } - - return rv; -} - -OP_InputStream T_VFS::read( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return OP_InputStream( ); - } - - const auto np( path.normalize( ) ); - auto& pi( p< T_VFSPrivate_ >( ) ); - OP_InputStream rv( pi.userDir_->read( np ) ); - const auto nd( pi.drivers_.size( ) ); - for ( uint32_t i = nd ; i != 0 && !rv ; i -- ) { - rv = pi.drivers_[ i - 1 ]->read( np ); - } - return rv; -} - -OP_File T_VFS::file( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return OP_File( ); - } - - const auto np( path.normalize( ) ); - auto& pi( p< T_VFSPrivate_ >( ) ); - OP_File rv( pi.userDir_->file( np ) ); - const auto nd( pi.drivers_.size( ) ); - for ( uint32_t i = nd ; i != 0 && !rv ; i -- ) { - rv = pi.drivers_[ i - 1 ]->file( np ); - } - - return rv; -} - -/*----------------------------------------------------------------------------*/ - -OP_File T_VFS::file( T_VFSPath const& path , E_FileMode mode ) const -{ - if ( mode == E_FileMode::READ_ONLY ) { - return file( path ); - } else if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return OP_File( ); - } else { - return dynamic_cast< T_VFSUserDirectory_* >( - p< T_VFSPrivate_ >( ).userDir_.get( ) ) - ->file( path.normalize( ) , mode ); - } -} - -OP_OutputStream T_VFS::write( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return OP_OutputStream( ); - } else { - return dynamic_cast< T_VFSUserDirectory_* >( - p< T_VFSPrivate_ >( ).userDir_.get( ) ) - ->write( path.normalize( ) ); - } -} - -bool T_VFS::mkdir( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return false; - } else { - return dynamic_cast< T_VFSUserDirectory_* >( - p< T_VFSPrivate_ >( ).userDir_.get( ) ) - ->mkdir( path.normalize( ) ); - } -} - -bool T_VFS::rmdir( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return false; - } else { - return dynamic_cast< T_VFSUserDirectory_* >( - p< T_VFSPrivate_ >( ).userDir_.get( ) ) - ->rmdir( path.normalize( ) ); - } -} - -bool T_VFS::rm( T_VFSPath const& path ) const -{ - if ( path.type( ) != E_VFSPathType::ABSOLUTE ) { - return false; - } else { - return dynamic_cast< T_VFSUserDirectory_* >( - p< T_VFSPrivate_ >( ).userDir_.get( ) ) - ->rm( path.normalize( ) ); - } -} - -bool T_VFS::move( T_VFSPath const& from , T_VFSPath const& to ) const -{ - if ( from.type( ) != E_VFSPathType::ABSOLUTE ) { - return false; - } - - const auto nFrom( from.normalize( ) ); - if ( from.elements( ) == 0 ) { - return false; - } - - T_VFSPath nTo; - if ( to.type( ) == E_VFSPathType::ABSOLUTE ) { - nTo = to.normalize( ); - } else if ( to.type( ) == E_VFSPathType::RELATIVE ) { - nTo = T_VFSPath( nFrom , T_VFSPath( ".." , to ) ).normalize( ); - } else { - return false; - } - if ( nTo.elements( ) == 0 ) { - return false; - } - - return dynamic_cast< T_VFSUserDirectory_* >( - p< T_VFSPrivate_ >( ).userDir_.get( ) ) - ->move( nFrom , nTo ); -} diff --git a/src/VFSDrivers.cc b/src/VFSDrivers.cc deleted file mode 100644 index dc93d1e..0000000 --- a/src/VFSDrivers.cc +++ /dev/null @@ -1,614 +0,0 @@ -/******************************************************************************/ -/* VIRTUAL FILE SYSTEM - NON-ESSENTIAL DRIVERS ********************************/ -/******************************************************************************/ - -#include -#include -#include -#include -using namespace lw; - - -/*= T_VFSDataIndexPrivate_ ===================================================*/ - -namespace { -struct T_VFSDataIndexPrivate_ -{ - // Information about an entry. - struct T_EntryInfo { - uint32_t index; - bool isFile; - }; - - const uint32_t magic_; - T_KeyValueTable< T_VFSPath , T_EntryInfo > entries_; - T_MultiArray< T_String > dirEntries_; - T_Array< T_VFSDataIndex::T_FileInfo > files_; - - // --------------------------------------------------------------------- - - explicit T_VFSDataIndexPrivate_( - uint32_t magic ); - - // --------------------------------------------------------------------- - - // Read the index from a stream - bool readIndex( - T_BinaryReader& reader ); - // Free the index - void free( ); - - // --------------------------------------------------------------------- - - // Get the type of an entry - E_VFSEntryType typeOf( T_VFSPath const& path ) const; - - // List a directory - bool list( - T_VFSPath const& path , - T_Array< T_VFSPath >& values , - T_HashIndex& index ) const; - - // Returns the file information record for a given path - T_VFSDataIndex::T_FileInfo const* getFileInfo( - T_VFSPath const& path ) const; -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -inline T_VFSDataIndexPrivate_::T_VFSDataIndexPrivate_( - uint32_t magic ) - : magic_( magic ) -{ } - -/*----------------------------------------------------------------------------*/ - -inline bool T_VFSDataIndexPrivate_::readIndex( - T_BinaryReader& reader ) -{ - /* - * FIXME clean this up later - * - * Format: - * - * magic - * version - * root directory - * other directories - * file data - * - * a directory: - * number of entries - * list of entries - * - * a directory entry: - * Entry's name (T_String) - * is file? (0/1) - * if it's a file: - * size (uint32_t) - * offset relative to start of data (uint32_t) - * - * size of a directory entry: - * size( name ) + 4 + isFile ? 8 : 0 - * - * size of a directory list: - * 4 + sum( size( entry ) for all entries ) - * - */ - if ( reader.read< uint32_t >( ) != magic_ ) { - return false; - } - if ( reader.read< uint32_t >( ) != 0 ) { - return false; - } - - const auto inSize( reader.stream( ).size( ) ); - T_RingBuffer< T_VFSPath > directories; - directories.put( T_VFSPath( "/" ) ); - entries_.add( T_VFSPath( "/" ) , T_EntryInfo{ 0 , false } ); - uint32_t dirReserved( 1 ); - - T_VFSPath current; - while ( directories.size( ) ) { - directories.readNext( current ); - dirEntries_.next( ); - - const auto nEntries( reader.read< uint32_t >( ) ); - for ( uint32_t i = 0 ; i < nEntries ; i ++ ) { - T_String name( reader.read< T_String >( ) ); - const T_VFSPath path( current , name ); - - const bool isFile( reader.read< uint8_t >( ) ); - const uint32_t index( isFile ? files_.size( ) : dirReserved ); - dirEntries_.add( name ); - if ( !entries_.add( path , T_EntryInfo{ index , isFile } ) ) { - return false; - } - - if ( isFile ) { - const auto size( reader.read< uint32_t >( ) ); - const auto offset( reader.read< uint32_t >( ) ); - if ( offset >= inSize || offset + size > inSize ) { - return false; - } - files_.add( T_VFSDataIndex::T_FileInfo{ size , offset } ); - } else { - directories.put( path ); - dirReserved ++; - } - } - } - - return dirReserved == dirEntries_.size( ); -} - -inline void T_VFSDataIndexPrivate_::free( ) -{ - entries_.free( ); - dirEntries_.free( ); - files_.free( ); -} - -/*----------------------------------------------------------------------------*/ - -inline E_VFSEntryType T_VFSDataIndexPrivate_::typeOf( - T_VFSPath const& path ) const -{ - T_EntryInfo const* eptr( entries_.get( path ) ); - if ( eptr == nullptr ) { - return E_VFSEntryType::NONE; - } - return eptr->isFile ? E_VFSEntryType::FILE : E_VFSEntryType::DIRECTORY; -} - -inline bool T_VFSDataIndexPrivate_::list( - T_VFSPath const& path , - T_Array< T_VFSPath >& values , - T_HashIndex& index ) const -{ - T_EntryInfo const* eptr( entries_.get( path ) ); - if ( eptr == nullptr || eptr->isFile ) { - return false; - } - - const auto first( dirEntries_.firstOf( eptr->index ) ); - const auto size( dirEntries_.sizeOf( eptr->index ) ); - for ( uint32_t i = 0 ; i < size ; i ++ ) { - const T_VFSPath p( dirEntries_[ i + first ] ); - const uint32_t hash( ComputeHash( p ) ); - uint32_t idx( index.first( hash ) ); - while ( idx != T_HashIndex::INVALID_INDEX ) { - if ( values[ idx ] == p ) { - break; - } - idx = index.next( idx ); - } - if ( idx == T_HashIndex::INVALID_INDEX ) { - index.add( hash ); - values.add( p ); - } - } - return true; -} - -inline T_VFSDataIndex::T_FileInfo const* T_VFSDataIndexPrivate_::getFileInfo( - T_VFSPath const& path ) const -{ - T_EntryInfo const* eptr( entries_.get( path ) ); - if ( eptr == nullptr || !eptr->isFile ) { - return nullptr; - } - return &files_[ eptr->index ]; -} - - -/*= T_VFSDataIndex ===========================================================*/ - -T_VFSDataIndex::T_VFSDataIndex( - uint32_t magic ) - : A_PrivateImplementation( new T_VFSDataIndexPrivate_( magic ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -bool T_VFSDataIndex::readIndex( - T_BinaryReader& reader ) -{ - return p< T_VFSDataIndexPrivate_ >( ).readIndex( reader ); -} - -void T_VFSDataIndex::free( ) -{ - return p< T_VFSDataIndexPrivate_ >( ).free( ); -} - -/*----------------------------------------------------------------------------*/ - -E_VFSEntryType T_VFSDataIndex::typeOf( - T_VFSPath const& path ) const -{ - return p< T_VFSDataIndexPrivate_ >( ).typeOf( path ); -} - -bool T_VFSDataIndex::list( - T_VFSPath const& path , - T_Array< T_VFSPath >& values , - T_HashIndex& index ) const -{ - return p< T_VFSDataIndexPrivate_ >( ).list( path , values , index ); -} - -T_VFSDataIndex::T_FileInfo const* T_VFSDataIndex::getFileInfo( - T_VFSPath const& path ) const -{ - return p< T_VFSDataIndexPrivate_ >( ).getFileInfo( path ); -} - - -/*= T_VFSRomDriverStream_ ====================================================*/ - -namespace lw { - -M_CLASS_POINTERS( VFSRomDriverStream_ ); -class T_VFSRomDriverStream_ : public A_InputStream -{ - private: - RP_VFSRomDriverStream_& head_; - T_ReadWriteMutex& mutex_; - - RP_VFSRomDriverStream_ prev_; - RP_VFSRomDriverStream_ next_; - OP_MemoryInputStream actual_; - - public: - T_VFSRomDriverStream_( ) = delete; - T_VFSRomDriverStream_( T_VFSRomDriverStream_ const& ) = delete; - T_VFSRomDriverStream_( T_VFSRomDriverStream_&& ) = delete; - - T_VFSRomDriverStream_( RP_VFSRomDriverStream_& head , - T_ReadWriteMutex& mutex , - OP_MemoryInputStream&& stream ); - ~T_VFSRomDriverStream_( ); - - size_t read( void* data , size_t size ) override; - - void disable( ); -}; - -} - -/*----------------------------------------------------------------------------*/ - -T_VFSRomDriverStream_::T_VFSRomDriverStream_( RP_VFSRomDriverStream_& head , - T_ReadWriteMutex& mutex , - OP_MemoryInputStream&& stream ) - : A_InputStream( stream->position( ) , stream->size( ) ) , - head_( head ) , mutex_( mutex ) , - prev_( nullptr ) , next_( head ) , - actual_( std::move( stream ) ) -{ - head = this; - if ( next_ ) { - next_->prev_ = this; - } -} - -T_VFSRomDriverStream_::~T_VFSRomDriverStream_( ) -{ - T_WriteLock lock( mutex_ ); - disable( ); -} - -size_t T_VFSRomDriverStream_::read( void* data , size_t size ) -{ - T_ReadLock lock( mutex_ ); - if ( actual_ ) { - return actual_->read( data , size ); - } else { - throw X_StreamError( E_StreamError::UNAVAILABLE ); - } -} - -void T_VFSRomDriverStream_::disable( ) -{ - actual_.clear( ); - if ( prev_ == nullptr ) { - head_ = next_; - } else { - prev_->next_ = next_; - } - if ( next_ != nullptr ) { - next_->prev_ = prev_; - } -} - - -/*= T_VFSRomDriverPrivate_ ===================================================*/ - -struct T_VFSRomDriverPrivate_ -{ - uint8_t const* data_; - uint32_t size_; - T_VFSDataIndex index_; - T_ReadWriteMutex mutex_; - T_VFSRomDriverStream_* streams_; - - T_VFSRomDriverPrivate_( - uint8_t const* const data , - uint32_t const size ); -}; - -/*----------------------------------------------------------------------------*/ - -inline T_VFSRomDriverPrivate_::T_VFSRomDriverPrivate_( - uint8_t const* const data , - uint32_t const size ) - : data_( data ) , size_( size ) , - index_( T_VFSRomDriver::C_MAGIC ) , - streams_( nullptr ) -{ - assert( data_ != nullptr ); - assert( size_ > 0 ); -} - - -/*= T_VFSRomDriver ===========================================================*/ - -constexpr uint32_t T_VFSRomDriver::C_MAGIC; - -/*----------------------------------------------------------------------------*/ - -T_VFSRomDriver::T_VFSRomDriver( - uint8_t const* const data , - uint32_t const size ) - : A_PrivateImplementation( new T_VFSRomDriverPrivate_( data , size ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -uint8_t const* T_VFSRomDriver::data( ) const -{ - return p< T_VFSRomDriverPrivate_ >( ).data_; -} - -uint32_t T_VFSRomDriver::size( ) const -{ - return p< T_VFSRomDriverPrivate_ >( ).size_; -} - -/*----------------------------------------------------------------------------*/ - -bool T_VFSRomDriver::init( ) -{ - auto& pi( p< T_VFSRomDriverPrivate_ >( ) ); - T_MemoryInputStream input( pi.data_ , pi.size_ ); - T_BinaryReader reader( input , E_Endian::NATIVE ); - bool rv; - try { - rv = pi.index_.readIndex( reader ); - } catch ( X_StreamError const& ) { - rv = false; - } - if ( !rv ) { - pi.index_.free( ); - } - return rv; -} - -void T_VFSRomDriver::shutdown( ) -{ - auto& pi( p< T_VFSRomDriverPrivate_ >( ) ); - T_WriteLock lock( pi.mutex_ ); - while ( pi.streams_ != nullptr ) { - pi.streams_->disable( ); - } - pi.index_.free( ); -} - -/*----------------------------------------------------------------------------*/ - -E_VFSEntryType T_VFSRomDriver::typeOf( T_VFSPath const& path ) -{ - auto& pi( p< T_VFSRomDriverPrivate_ >( ) ); - T_ReadLock lock( pi.mutex_ ); - return pi.index_.typeOf( path ); -} - -bool T_VFSRomDriver::list( T_VFSPath const& path , T_Array< T_VFSPath >& values , T_HashIndex& index ) -{ - auto& pi( p< T_VFSRomDriverPrivate_ >( ) ); - T_ReadLock lock( pi.mutex_ ); - return pi.index_.list( path , values , index ); -} - -OP_InputStream T_VFSRomDriver::read( T_VFSPath const& path ) -{ - auto& pi( p< T_VFSRomDriverPrivate_ >( ) ); - T_ReadLock lock( pi.mutex_ ); - T_VFSDataIndex::T_FileInfo const* p( pi.index_.getFileInfo( path ) ); - if ( p == nullptr ) { - return OP_InputStream( ); - } - - T_WriteLock wLock( lock.upgrade( ) ); - return NewOwned< T_VFSRomDriverStream_ >( pi.streams_ , pi.mutex_ , - NewOwned< T_MemoryInputStream >( pi.data_ + p->offset , p->size ) ); -} - - -/*= T_VFSDataFileDriverStream_ ===============================================*/ - -namespace lw { - -M_CLASS_POINTERS( VFSDataFileDriverStream_ ); -class T_VFSDataFileDriverStream_ : public A_InputStream -{ - private: - RP_VFSDataFileDriverStream_& head_; - T_Mutex& mutex_; - - RP_VFSDataFileDriverStream_ prev_; - RP_VFSDataFileDriverStream_ next_; - OP_FileInputStream actual_; - - public: - T_VFSDataFileDriverStream_( ) = delete; - T_VFSDataFileDriverStream_( T_VFSDataFileDriverStream_ const& ) = delete; - T_VFSDataFileDriverStream_( T_VFSDataFileDriverStream_&& ) = delete; - - T_VFSDataFileDriverStream_( RP_VFSDataFileDriverStream_& head , T_Mutex& mutex , - OP_FileInputStream&& stream ); - ~T_VFSDataFileDriverStream_( ); - - size_t read( void* data , size_t size ) override; - - void disable( ); -}; - -} - -/*----------------------------------------------------------------------------*/ - -T_VFSDataFileDriverStream_::T_VFSDataFileDriverStream_( - RP_VFSDataFileDriverStream_& head , T_Mutex& mutex , - OP_FileInputStream&& stream ) - : A_InputStream( stream->position( ) , stream->size( ) ) , - head_( head ) , mutex_( mutex ) , - prev_( nullptr ) , next_( head ) , - actual_( std::move( stream ) ) -{ - head = this; - if ( next_ ) { - next_->prev_ = this; - } -} - -T_VFSDataFileDriverStream_::~T_VFSDataFileDriverStream_( ) -{ - T_ScopeLock lock( mutex_ ); - disable( ); -} - -size_t T_VFSDataFileDriverStream_::read( void* data , size_t size ) -{ - T_ScopeLock lock( mutex_ ); - if ( actual_ ) { - return actual_->read( data , size ); - } else { - throw X_StreamError( E_StreamError::UNAVAILABLE ); - } -} - -void T_VFSDataFileDriverStream_::disable( ) -{ - actual_.clear( ); - if ( prev_ == nullptr ) { - head_ = next_; - } else { - prev_->next_ = next_; - } - if ( next_ != nullptr ) { - next_->prev_ = prev_; - } -} - - -/*= T_VFSDataFileDriverPrivate_ ==============================================*/ - -namespace { -struct T_VFSDataFileDriverPrivate_ -{ - T_Mutex mutex_; - OP_File file_; - T_VFSDataIndex index_; - T_VFSDataFileDriverStream_* streams_; - - explicit T_VFSDataFileDriverPrivate_( - OP_File&& file ); -}; -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_VFSDataFileDriverPrivate_::T_VFSDataFileDriverPrivate_( - OP_File&& file ) - : file_( std::move( file ) ) , - index_( T_VFSDataFileDriver::C_MAGIC ) , - streams_( nullptr ) -{ - assert( file_ ); -} - - -/*= T_VFSDataFileDriver ======================================================*/ - -T_VFSDataFileDriver::T_VFSDataFileDriver( OP_File&& file ) - : A_PrivateImplementation( new T_VFSDataFileDriverPrivate_( std::move( file ) ) ) -{ } - -/*----------------------------------------------------------------------------*/ - -T_File const& T_VFSDataFileDriver::dataFile( ) const -{ - return *( p< T_VFSDataFileDriverPrivate_ >( ).file_ ); -} - -/*----------------------------------------------------------------------------*/ - -bool T_VFSDataFileDriver::init( ) -{ - auto& pi( p< T_VFSDataFileDriverPrivate_ >( ) ); - bool rv; - try { - T_FileInputStream input( *pi.file_ , 0 ); - T_BinaryReader reader( input , E_Endian::NATIVE ); - rv = pi.index_.readIndex( reader ); - } catch ( X_StreamError const& ) { - rv = false; - } - if ( !rv ) { - pi.index_.free( ); - } - return rv; -} - -void T_VFSDataFileDriver::shutdown( ) -{ - auto& pi( p< T_VFSDataFileDriverPrivate_ >( ) ); - T_ScopeLock lock( pi.mutex_ ); - while ( pi.streams_ != nullptr ) { - pi.streams_->disable( ); - } - pi.index_.free( ); - pi.file_->close( ); -} - -/*----------------------------------------------------------------------------*/ - -E_VFSEntryType T_VFSDataFileDriver::typeOf( T_VFSPath const& path ) -{ - auto& pi( p< T_VFSDataFileDriverPrivate_ >( ) ); - T_ScopeLock lock( pi.mutex_ ); - return pi.index_.typeOf( path ); -} - -bool T_VFSDataFileDriver::list( T_VFSPath const& path , T_Array< T_VFSPath >& values , T_HashIndex& index ) -{ - auto& pi( p< T_VFSDataFileDriverPrivate_ >( ) ); - T_ScopeLock lock( pi.mutex_ ); - return pi.index_.list( path , values , index ); -} - -OP_InputStream T_VFSDataFileDriver::read( T_VFSPath const& path ) -{ - auto& pi( p< T_VFSDataFileDriverPrivate_ >( ) ); - T_ScopeLock lock( pi.mutex_ ); - T_VFSDataIndex::T_FileInfo const* p( pi.index_.getFileInfo( path ) ); - if ( p == nullptr ) { - return OP_InputStream( ); - } - pi.file_->position( p->offset ); - return NewOwned< T_VFSDataFileDriverStream_ >( pi.streams_ , pi.mutex_ , - NewOwned< T_FileInputStream >( *pi.file_ , 0 , p->size ) ); -} diff --git a/src/files.mk b/src/files.mk index 78bab9e..28885db 100644 --- a/src/files.mk +++ b/src/files.mk @@ -1,34 +1,18 @@ LIB_SOURCES = \ + src/DynLib.cc \ src/Files.cc \ src/HashIndex.cc \ src/MemoryStreams.cc \ src/Pointers.cc \ + src/SRDBinary.cc \ + src/SRDData.cc \ + src/SRDDefinitions.cc \ + src/SRDIO.cc \ + src/SRDParser.cc \ + src/SRDParserConfig.cc \ + src/SRDText.cc \ src/Streams.cc \ src/Strings.cc \ src/TemplateInstantiation.cc \ src/Utilities.cc \ # END - -# -# src/SRDBinary.cc \ -# src/SRDData.cc \ -# src/SRDDefinitions.cc \ -# src/SRDIO.cc \ -# src/SRDParser.cc \ -# src/SRDParserConfig.cc \ -# src/SRDPreproc.cc \ -# src/SRDPPCommands.cc \ -# src/SRDText.cc \ -# src/VFS.cc \ -# src/VFSDrivers.cc \ -# src/Console.cc \ -# src/ConsoleLogWriter.cc \ -# src/CwdFileLogger.cc \ -# src/DynLib.cc \ -# src/GameLoop.cc \ -# src/LW.cc \ -# src/Log.cc \ -# src/Messages.cc \ -# src/ModInterface.cc \ -# src/Mods.cc \ -# src/TextFileLogger.cc diff --git a/tests/alloc-pool.cc b/tests/alloc-pool.cc index d82fa43..6f610d1 100644 --- a/tests/alloc-pool.cc +++ b/tests/alloc-pool.cc @@ -1,7 +1,7 @@ -#include -#include +#include +#include #include -using namespace lw; +using namespace ebcl; class AllocPoolTest : public CppUnit::TestFixture diff --git a/tests/console-edit.cc b/tests/console-edit.cc deleted file mode 100644 index 8338f5b..0000000 --- a/tests/console-edit.cc +++ /dev/null @@ -1,468 +0,0 @@ -#include -#include -using namespace lw; - - -class ConsoleEditTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( ConsoleEditTest ); - CPPUNIT_TEST( testEmpty ); - CPPUNIT_TEST( testSetContents ); - CPPUNIT_TEST( testReset ); - - CPPUNIT_TEST( testCursorStart ); - CPPUNIT_TEST( testCursorStartEmpty ); - CPPUNIT_TEST( testCursorEnd ); - CPPUNIT_TEST( testCursorEndEmpty ); - CPPUNIT_TEST( testCursorLeft ); - CPPUNIT_TEST( testCursorLeftStart ); - CPPUNIT_TEST( testCursorRight ); - CPPUNIT_TEST( testCursorRightEnd ); - - CPPUNIT_TEST( testAppendCharacter ); - CPPUNIT_TEST( testInsertCharacter ); - CPPUNIT_TEST( testAppendBuffer ); - CPPUNIT_TEST( testInsertBuffer ); - - CPPUNIT_TEST( testPrevWordStart ); - CPPUNIT_TEST( testPrevWordInWord ); - CPPUNIT_TEST( testPrevWordSpaces ); - CPPUNIT_TEST( testNextWordEnd ); - CPPUNIT_TEST( testNextWordInWord ); - CPPUNIT_TEST( testNextWordSpaces ); - - CPPUNIT_TEST( testRmCharAtEnd ); - CPPUNIT_TEST( testRmCharLast ); - CPPUNIT_TEST( testRmCharMiddle ); - - CPPUNIT_TEST( testRmWordAtEnd ); - CPPUNIT_TEST( testRmWordMiddle ); - CPPUNIT_TEST( testRmWordAtStart ); - - CPPUNIT_TEST( testRmRestAtStart ); - CPPUNIT_TEST( testRmRestMiddle ); - CPPUNIT_TEST( testRmRestAtEnd ); - CPPUNIT_TEST_SUITE_END( ); - -public: - void testEmpty( ); - void testSetContents( ); - void testReset( ); - - void testCursorStart( ); - void testCursorStartEmpty( ); - void testCursorEnd( ); - void testCursorEndEmpty( ); - void testCursorLeft( ); - void testCursorLeftStart( ); - void testCursorRight( ); - void testCursorRightEnd( ); - - void testAppendCharacter( ); - void testInsertCharacter( ); - void testAppendBuffer( ); - void testInsertBuffer( ); - - void testPrevWordStart( ); - void testPrevWordInWord( ); - void testPrevWordSpaces( ); - void testNextWordEnd( ); - void testNextWordInWord( ); - void testNextWordSpaces( ); - - void testRmCharAtEnd( ); - void testRmCharLast( ); - void testRmCharMiddle( ); - - void testRmWordAtEnd( ); - void testRmWordMiddle( ); - void testRmWordAtStart( ); - - void testRmRestAtStart( ); - void testRmRestMiddle( ); - void testRmRestAtEnd( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( ConsoleEditTest ); - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testEmpty( ) -{ - T_ConsoleLineState s; - CPPUNIT_ASSERT( s.getContents( ) == "" ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.historyIndex( ) ); -} - -void ConsoleEditTest::testSetContents( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 1 ); - CPPUNIT_ASSERT( s.getContents( ) == str ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 1u , s.historyIndex( ) ); -} - -void ConsoleEditTest::testReset( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 1 ); - s.reset( ); - CPPUNIT_ASSERT( s.getContents( ) == "" ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.historyIndex( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testCursorStart( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorStartEmpty( ) -{ - T_ConsoleLineState s; - s.toStart( ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorEnd( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - s.toEnd( ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorEndEmpty( ) -{ - T_ConsoleLineState s; - s.toEnd( ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorLeft( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.left( ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 3u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorLeftStart( ) -{ - T_ConsoleLineState s; - s.left( ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorRight( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - s.right( ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 1u , s.pos( ) ); -} - -void ConsoleEditTest::testCursorRightEnd( ) -{ - T_ConsoleLineState s; - s.right( ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testAppendCharacter( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.insert( 't' ); - s.insert( 0x20ac ); - s.insert( 's' ); - s.insert( 't' ); - CPPUNIT_ASSERT( s.getContents( ) == str ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.historyIndex( ) ); -} - -void ConsoleEditTest::testInsertCharacter( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.insert( 0x20ac ); - s.insert( 's' ); - s.insert( 't' ); - s.toStart( ); - s.insert( 't' ); - CPPUNIT_ASSERT( s.getContents( ) == str ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 1u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.historyIndex( ) ); -} - -void ConsoleEditTest::testAppendBuffer( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_Buffer< uint32_t > b( 4 ); - b[ 0 ] = b[ 3 ] = 't'; - b[ 1 ] = 0x20ac; - b[ 2 ] = 's'; - - T_ConsoleLineState s; - s.insert( b , 4 ); - CPPUNIT_ASSERT( s.getContents( ) == str ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.historyIndex( ) ); -} - -void ConsoleEditTest::testInsertBuffer( ) -{ - const T_String str( "t\xe2\x82\xacst" ); - T_Buffer< uint32_t > b( 3 ); - b[ 0 ] = 't'; - b[ 1 ] = 0x20ac; - b[ 2 ] = 's'; - - T_ConsoleLineState s; - s.insert( 't' ); - s.toStart( ); - s.insert( b , 3 ); - - CPPUNIT_ASSERT( s.getContents( ) == str ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 3u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.historyIndex( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testPrevWordStart( ) -{ - const T_String str( "t\xe2\x82\xacst " ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - s.prevWord( ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); -} - -void ConsoleEditTest::testPrevWordInWord( ) -{ - const T_String str( " t\xe2\x82\xacst" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.prevWord( ); - CPPUNIT_ASSERT_EQUAL( 1u , s.pos( ) ); -} - -void ConsoleEditTest::testPrevWordSpaces( ) -{ - const T_String str( " t\xe2\x82\xacst " ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.prevWord( ); - CPPUNIT_ASSERT_EQUAL( 1u , s.pos( ) ); -} - -void ConsoleEditTest::testNextWordEnd( ) -{ - const T_String str( "t\xe2\x82\xacst " ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.nextWord( ); - CPPUNIT_ASSERT_EQUAL( s.size( ) , s.pos( ) ); -} - -void ConsoleEditTest::testNextWordInWord( ) -{ - const T_String str( "t\xe2\x82\xacst " ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - s.nextWord( ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); -} - -void ConsoleEditTest::testNextWordSpaces( ) -{ - const T_String str( " t\xe2\x82\xacst " ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - s.nextWord( ); - CPPUNIT_ASSERT_EQUAL( 6u , s.pos( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testRmCharAtEnd( ) -{ - const T_String str( "test" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.removeCharacter( ); - CPPUNIT_ASSERT( s.getContents( ) == "test" ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); -} - -void ConsoleEditTest::testRmCharLast( ) -{ - const T_String str( "test" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.left( ); - s.removeCharacter( ); - CPPUNIT_ASSERT( s.getContents( ) == "tes" ); - CPPUNIT_ASSERT_EQUAL( 3u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 3u , s.size( ) ); -} - -void ConsoleEditTest::testRmCharMiddle( ) -{ - const T_String str( "test" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - s.removeCharacter( ); - CPPUNIT_ASSERT( s.getContents( ) == "est" ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 3u , s.size( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testRmWordAtEnd( ) -{ - const T_String str( "test blah" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - T_Buffer< uint32_t > cpb; - uint32_t cpl( 572 ); - s.removeWord( cpb , cpl ); - CPPUNIT_ASSERT( s.getContents( ) == "test " ); - CPPUNIT_ASSERT_EQUAL( 5u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 5u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , cpl ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 'b' ) , cpb[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 'l' ) , cpb[ 1 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 'a' ) , cpb[ 2 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 'h' ) , cpb[ 3 ] ); -} - -void ConsoleEditTest::testRmWordMiddle( ) -{ - const T_String str( "test blah" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.left( ); - s.left( ); - s.left( ); - s.left( ); - T_Buffer< uint32_t > cpb; - uint32_t cpl( 572 ); - s.removeWord( cpb , cpl ); - CPPUNIT_ASSERT( s.getContents( ) == "blah" ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 5u , cpl ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 't' ) , cpb[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 'e' ) , cpb[ 1 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 's' ) , cpb[ 2 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 't' ) , cpb[ 3 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( ' ' ) , cpb[ 4 ] ); -} - -void ConsoleEditTest::testRmWordAtStart( ) -{ - const T_String str( "test blah" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - T_Buffer< uint32_t > cpb; - uint32_t cpl( 572 ); - s.removeWord( cpb , cpl ); - CPPUNIT_ASSERT( s.getContents( ) == "test blah" ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 9u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 572u , cpl ); -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleEditTest::testRmRestAtStart( ) -{ - const T_String str( "test" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.toStart( ); - T_Buffer< uint32_t > cpb; - uint32_t cpl( 572 ); - s.removeRestOfLine( cpb , cpl ); - CPPUNIT_ASSERT( s.getContents( ) == "" ); - CPPUNIT_ASSERT_EQUAL( 0u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 0u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , cpl ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 't' ) , cpb[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 'e' ) , cpb[ 1 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 's' ) , cpb[ 2 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 't' ) , cpb[ 3 ] ); -} - -void ConsoleEditTest::testRmRestMiddle( ) -{ - const T_String str( "test" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - s.left( ); - s.left( ); - T_Buffer< uint32_t > cpb; - uint32_t cpl( 572 ); - s.removeRestOfLine( cpb , cpl ); - CPPUNIT_ASSERT( s.getContents( ) == "te" ); - CPPUNIT_ASSERT_EQUAL( 2u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 2u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 2u , cpl ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 's' ) , cpb[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 't' ) , cpb[ 1 ] ); -} - -void ConsoleEditTest::testRmRestAtEnd( ) -{ - const T_String str( "test" ); - T_ConsoleLineState s; - s.setContents( str , 0 ); - T_Buffer< uint32_t > cpb; - uint32_t cpl( 572 ); - s.removeRestOfLine( cpb , cpl ); - CPPUNIT_ASSERT( s.getContents( ) == "test" ); - CPPUNIT_ASSERT_EQUAL( 4u , s.pos( ) ); - CPPUNIT_ASSERT_EQUAL( 4u , s.size( ) ); - CPPUNIT_ASSERT_EQUAL( 572u , cpl ); -} diff --git a/tests/console-text.cc b/tests/console-text.cc deleted file mode 100644 index 233aabf..0000000 --- a/tests/console-text.cc +++ /dev/null @@ -1,405 +0,0 @@ -#include -#include -using namespace lw; - - -class ConsoleTextTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( ConsoleTextTest ); - CPPUNIT_TEST( testEmpty ); - CPPUNIT_TEST( testSimpleString ); - - CPPUNIT_TEST( testChangeStyle ); - CPPUNIT_TEST( testChangeStyleTwice ); - CPPUNIT_TEST( testChangeStyleAtEnd ); - - CPPUNIT_TEST( testChangeColor ); - CPPUNIT_TEST( testChangeColorTwice ); - CPPUNIT_TEST( testChangeColorAtEnd ); - - CPPUNIT_TEST( testChangeColorAndStyle ); - - CPPUNIT_TEST( testTextCopyCons ); - CPPUNIT_TEST( testTextCopyAss ); - CPPUNIT_TEST( testTextMoveCons ); - CPPUNIT_TEST( testTextMoveAss ); - CPPUNIT_TEST( testTextSwap ); - - CPPUNIT_TEST( testBuilderCopyCons ); - CPPUNIT_TEST( testBuilderCopyAss ); - CPPUNIT_TEST( testBuilderMoveCons ); - CPPUNIT_TEST( testBuilderMoveAss ); - CPPUNIT_TEST( testBuilderSwap ); - CPPUNIT_TEST_SUITE_END( ); - -public: - void testEmpty( ); - void testSimpleString( ); - - void testChangeStyle( ); - void testChangeStyleTwice( ); - void testChangeStyleAtEnd( ); - - void testChangeColor( ); - void testChangeColorTwice( ); - void testChangeColorAtEnd( ); - - void testChangeColorAndStyle( ); - - void testTextCopyCons( ); - void testTextCopyAss( ); - void testTextMoveCons( ); - void testTextMoveAss( ); - void testTextSwap( ); - - void testBuilderCopyCons( ); - void testBuilderCopyAss( ); - void testBuilderMoveCons( ); - void testBuilderMoveAss( ); - void testBuilderSwap( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( ConsoleTextTest ); - -/*----------------------------------------------------------------------------*/ - -void ConsoleTextTest::testEmpty( ) -{ - T_TextBuilder tb; - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "" ); -} - -void ConsoleTextTest::testSimpleString( ) -{ - T_TextBuilder tb; - tb << "test"; - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleTextTest::testChangeStyle( ) -{ - T_TextBuilder tb; - tb << "te"; - tb.addStyle( E_TextStyle::BOLD ); - tb << "st"; - - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - if ( i < 2 ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - } else { - CPPUNIT_ASSERT_EQUAL( uint8_t( E_TextStyle::BOLD ) , t.styleAt( i ) ); - } - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testChangeStyleTwice( ) -{ - T_TextBuilder tb; - tb << "te"; - tb.addStyle( E_TextStyle::BOLD ); - tb.addStyle( E_TextStyle::ITALIC ); - tb << "st"; - - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - if ( i < 2 ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - } else { - CPPUNIT_ASSERT_EQUAL( - uint8_t( uint8_t( E_TextStyle::BOLD ) | uint8_t( E_TextStyle::ITALIC ) ) , - t.styleAt( i ) ); - } - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testChangeStyleAtEnd( ) -{ - T_TextBuilder tb; - tb << "test"; - tb.addStyle( E_TextStyle::BOLD ); - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleTextTest::testChangeColor( ) -{ - T_TextBuilder tb; - tb << "te"; - tb.setColor( E_TextColor::RED ); - tb << "st"; - - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - if ( i < 2 ) { - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } else { - CPPUNIT_ASSERT( E_TextColor::RED == t.colorAt( i ).type ); - } - } -} - -void ConsoleTextTest::testChangeColorTwice( ) -{ - T_TextBuilder tb; - tb << "te"; - tb.setColor( E_TextColor::RED ); - tb.setColor( E_TextColor::GREEN ); - tb << "st"; - - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - if ( i < 2 ) { - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } else { - CPPUNIT_ASSERT( E_TextColor::GREEN == t.colorAt( i ).type ); - } - } -} - -void ConsoleTextTest::testChangeColorAtEnd( ) -{ - T_TextBuilder tb; - tb << "test"; - tb.setColor( E_TextColor::GREEN ); - - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleTextTest::testChangeColorAndStyle( ) -{ - T_TextBuilder tb; - tb.addStyle( E_TextStyle::BOLD ); - tb << "te"; - tb.removeStyle( E_TextStyle::BOLD ); - tb.setColor( E_TextColor::GREEN ); - tb << "st"; - - T_Text t( tb ); - CPPUNIT_ASSERT( t.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - if ( i < 2 ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( E_TextStyle::BOLD ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - } else { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::GREEN == t.colorAt( i ).type ); - } - } -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleTextTest::testTextCopyCons( ) -{ - T_TextBuilder tb; - tb << "test"; - - T_Text t( tb ); - T_Text t2( t ); - - CPPUNIT_ASSERT( t.string( ) == "test" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testTextCopyAss( ) -{ - T_TextBuilder tb; - tb << "test"; - T_Text t( tb ); - - tb.clear( ); - tb << "blargh"; - T_Text t2( tb ); - - t2 = t; - - CPPUNIT_ASSERT( t.string( ) == "test" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testTextMoveCons( ) -{ - T_TextBuilder tb; - tb << "test"; - T_Text t( tb ); - T_Text t2( std::move( t ) ); - - CPPUNIT_ASSERT( t.string( ) == "" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testTextMoveAss( ) -{ - T_TextBuilder tb; - tb << "te"; - T_Text t2( tb ); - tb << "st"; - T_Text t( tb ); - - t2 = std::move( t ); - - CPPUNIT_ASSERT( t.string( ) == "" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testTextSwap( ) -{ - T_TextBuilder tb; - tb << "test"; - T_Text t( tb ); - - tb.clear( ); - tb << E_TextStyle::BOLD << "blah"; - T_Text t2( tb ); - - swap( t , t2 ); - - CPPUNIT_ASSERT( t.string( ) == "blah" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( E_TextStyle::BOLD ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -/*----------------------------------------------------------------------------*/ - -void ConsoleTextTest::testBuilderCopyCons( ) -{ - T_TextBuilder tb; - tb << "test"; - - T_TextBuilder tb2( tb ); - T_Text t( tb ) , t2( tb2 ); - - CPPUNIT_ASSERT( t.string( ) == "test" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testBuilderCopyAss( ) -{ - T_TextBuilder tb , tb2; - tb << "test"; - tb2 << "blah"; - tb2 = tb; - T_Text t( tb ) , t2( tb2 ); - - CPPUNIT_ASSERT( t.string( ) == "test" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testBuilderMoveCons( ) -{ - T_TextBuilder tb; - tb << "test"; - - T_TextBuilder tb2( std::move( tb ) ); - T_Text t( tb ) , t2( tb2 ); - - CPPUNIT_ASSERT( t.string( ) == "" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testBuilderMoveAss( ) -{ - T_TextBuilder tb , tb2; - tb << "test"; - tb2 << "blah"; - tb2 = std::move( tb ); - - T_Text t( tb ) , t2( tb2 ); - - CPPUNIT_ASSERT( t.string( ) == "" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - -void ConsoleTextTest::testBuilderSwap( ) -{ - T_TextBuilder tb , tb2; - tb << "test"; - tb2 << E_TextStyle::BOLD << "blah"; - swap( tb , tb2 ); - - T_Text t( tb ) , t2( tb2 ); - - CPPUNIT_ASSERT( t.string( ) == "blah" ); - CPPUNIT_ASSERT( t2.string( ) == "test" ); - for ( int i = 0 ; i < 4 ; i ++ ) { - CPPUNIT_ASSERT_EQUAL( uint8_t( E_TextStyle::BOLD ) , t.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t.colorAt( i ).type ); - CPPUNIT_ASSERT_EQUAL( uint8_t( 0 ) , t2.styleAt( i ) ); - CPPUNIT_ASSERT( E_TextColor::WHITE == t2.colorAt( i ).type ); - } -} - diff --git a/tests/list.mk b/tests/list.mk index f033b11..e6ddbc5 100644 --- a/tests/list.mk +++ b/tests/list.mk @@ -1,4 +1,6 @@ TESTS = \ + alloc-pool \ + ring-buffer \ buffers \ ptr-owned \ ptr-shared \ @@ -22,34 +24,12 @@ TESTS = \ hash-index \ key-value-table \ object-table \ - -#TESTS = \ -# alloc-pool \ -# ring-buffer \ -# stream-file-input \ -# srd-bin-reader \ -# srd-bin-writer \ -# srd-lexer \ -# srd-text-writer \ -# srd-mem-target \ -# srd-parser \ -# srd-parser-defs \ -# srd-parser-cfg \ -# srd-preproc-core \ -# srd-preproc-cmd-core \ -# srd-preproc-cmd-variables \ -# srd-preproc-cmd-functions \ -# srd-preproc-cmd-macros \ -# srd-preproc-cmd-introspect \ -# srd-preproc-cmd-compare \ -# srd-preproc-cmd-casts \ -# srd-preproc-cmd-arithmetic \ -# srd-preproc-cmd-logic \ -# srd-preproc-cmd-strings \ -# srd-preproc-cmd-misc \ -# srd-preproc-cmd-input \ -# srd-preproc-tracking \ -# log-data \ -# console-text \ -# console-edit \ -# vfs + srd-mem-target \ + srd-lexer \ + srd-text-writer \ + srd-bin-reader \ + srd-bin-writer \ + srd-parser-defs \ + srd-parser-cfg \ + srd-parser \ +# END diff --git a/tests/log-data.cc b/tests/log-data.cc deleted file mode 100644 index 009c1f0..0000000 --- a/tests/log-data.cc +++ /dev/null @@ -1,649 +0,0 @@ -#include -#include -using namespace lw; - - -class LogLevelTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( LogLevelTest ); - CPPUNIT_TEST( testToString ); - CPPUNIT_TEST_SUITE_END( ); - -public: - void testToString( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( LogLevelTest ); - -/*----------------------------------------------------------------------------*/ - -class LogPathTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( LogPathTest ); - CPPUNIT_TEST( testEmpty ); - - CPPUNIT_TEST( testArrayCopy ); - CPPUNIT_TEST( testArrayCopyEmpty ); - CPPUNIT_TEST( testArrayCopyInvalidControl ); - CPPUNIT_TEST( testArrayCopyInvalidSlash ); - CPPUNIT_TEST( testArrayCopyInvalidEmpty ); - - CPPUNIT_TEST( testArrayMove ); - CPPUNIT_TEST( testArrayMoveEmpty ); - CPPUNIT_TEST( testArrayMoveInvalidControl ); - CPPUNIT_TEST( testArrayMoveInvalidSlash ); - CPPUNIT_TEST( testArrayMoveInvalidEmpty ); - - CPPUNIT_TEST( testInitList ); - CPPUNIT_TEST( testInitListEmpty ); - CPPUNIT_TEST( testInitListInvalidControl ); - CPPUNIT_TEST( testInitListInvalidSlash ); - CPPUNIT_TEST( testInitListInvalidEmpty ); - - CPPUNIT_TEST( testFromStringEmpty ); - CPPUNIT_TEST( testFromStringSlash ); - CPPUNIT_TEST( testFromStringSlashes ); - CPPUNIT_TEST( testFromStringValid ); - CPPUNIT_TEST( testFromStringValidSlashes ); - CPPUNIT_TEST( testFromStringValidInitialSlash ); - CPPUNIT_TEST( testFromStringValidTrailingSlash ); - CPPUNIT_TEST( testFromStringInvalid ); - - CPPUNIT_TEST( testSwap ); - - CPPUNIT_TEST( testParentEmpty ); - CPPUNIT_TEST( testParentOne ); - CPPUNIT_TEST( testParentValid ); - CPPUNIT_TEST( testParentInvalidChild ); - CPPUNIT_TEST( testParentInvalid ); - - CPPUNIT_TEST( testChildValid ); - CPPUNIT_TEST( testChildInvalidName ); - CPPUNIT_TEST( testChildInvalidParent ); - - CPPUNIT_TEST( testToStringEmpty ); - CPPUNIT_TEST( testToStringValid ); - CPPUNIT_TEST( testToStringInvalidSlash ); - CPPUNIT_TEST( testToStringInvalidControl ); - CPPUNIT_TEST( testToStringInvalidEmpty ); - - CPPUNIT_TEST( testIsParentYes ); - CPPUNIT_TEST( testIsParentNo ); - CPPUNIT_TEST( testIsParentYesInvalidParent ); - CPPUNIT_TEST( testIsParentYesInvalidChild ); - CPPUNIT_TEST( testIsParentNoInvalidParent ); - CPPUNIT_TEST( testIsParentNoInvalidChild ); - - CPPUNIT_TEST( testEquals ); - CPPUNIT_TEST( testNotEquals ); - CPPUNIT_TEST_SUITE_END( ); - -public: - void testEmpty( ); - - void testArrayCopy( ); - void testArrayCopyEmpty( ); - void testArrayCopyInvalidControl( ); - void testArrayCopyInvalidSlash( ); - void testArrayCopyInvalidEmpty( ); - - void testArrayMove( ); - void testArrayMoveEmpty( ); - void testArrayMoveInvalidControl( ); - void testArrayMoveInvalidSlash( ); - void testArrayMoveInvalidEmpty( ); - - void testInitList( ); - void testInitListEmpty( ); - void testInitListInvalidControl( ); - void testInitListInvalidSlash( ); - void testInitListInvalidEmpty( ); - - void testFromStringEmpty( ); - void testFromStringSlash( ); - void testFromStringSlashes( ); - void testFromStringValid( ); - void testFromStringValidSlashes( ); - void testFromStringValidInitialSlash( ); - void testFromStringValidTrailingSlash( ); - void testFromStringInvalid( ); - - void testSwap( ); - - void testParentEmpty( ); - void testParentOne( ); - void testParentValid( ); - void testParentInvalidChild( ); - void testParentInvalid( ); - - void testChildValid( ); - void testChildInvalidName( ); - void testChildInvalidParent( ); - - void testToStringEmpty( ); - void testToStringValid( ); - void testToStringInvalidSlash( ); - void testToStringInvalidControl( ); - void testToStringInvalidEmpty( ); - - void testIsParentYes( ); - void testIsParentNo( ); - void testIsParentYesInvalidParent( ); - void testIsParentYesInvalidChild( ); - void testIsParentNoInvalidParent( ); - void testIsParentNoInvalidChild( ); - - void testEquals( ); - void testNotEquals( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( LogPathTest ); - -/*----------------------------------------------------------------------------*/ - -void LogLevelTest::testToString( ) -{ - T_StringBuilder sb; - sb << E_LogLevel::TRACE << ' ' << E_LogLevel::DEBUG << ' ' - << E_LogLevel::INFO << ' ' << E_LogLevel::NOTICE << ' ' - << E_LogLevel::WARNING << ' ' << E_LogLevel::ERROR << ' ' - << E_LogLevel::CRITICAL; - - T_String s( std::move( sb ) ); - CPPUNIT_ASSERT( s == "trace debug info notice warning error critical" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testEmpty( ) -{ - T_LogPath lp; - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testArrayCopy( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "c" ) ); - - T_LogPath lp( test ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -void LogPathTest::testArrayCopyEmpty( ) -{ - T_Array< T_String > test; - T_LogPath lp( test ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -void LogPathTest::testArrayCopyInvalidControl( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "c\n" ) ); - - T_LogPath lp( test ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c\n" ); -} - -void LogPathTest::testArrayCopyInvalidSlash( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "c/" ) ); - - T_LogPath lp( test ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c/" ); -} - -void LogPathTest::testArrayCopyInvalidEmpty( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "" ) ); - - T_LogPath lp( test ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testArrayMove( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "c" ) ); - - RPC_String s0( &test[ 0 ] ); - RPC_String s1( &test[ 1 ] ); - RPC_String s2( &test[ 2 ] ); - - T_LogPath lp( std::move( test ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); - CPPUNIT_ASSERT_EQUAL( s0 , &lp[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( s1 , &lp[ 1 ] ); - CPPUNIT_ASSERT_EQUAL( s2 , &lp[ 2 ] ); -} - -void LogPathTest::testArrayMoveEmpty( ) -{ - T_Array< T_String > test; - T_LogPath lp( std::move( test ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -void LogPathTest::testArrayMoveInvalidControl( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "c\n" ) ); - - T_LogPath lp( std::move( test ) ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c\n" ); -} - -void LogPathTest::testArrayMoveInvalidSlash( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "c/" ) ); - - T_LogPath lp( std::move( test ) ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c/" ); -} - -void LogPathTest::testArrayMoveInvalidEmpty( ) -{ - T_Array< T_String > test; - test.add( T_String::Pooled( "a" ) ); - test.add( T_String::Pooled( "b" ) ); - test.add( T_String::Pooled( "" ) ); - - T_LogPath lp( std::move( test ) ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testInitList( ) -{ - T_LogPath lp{ "a" , "b" , "c" }; - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -void LogPathTest::testInitListEmpty( ) -{ - T_LogPath lp{ }; - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -void LogPathTest::testInitListInvalidControl( ) -{ - T_LogPath lp{ "a" , "b" , "c\n" }; - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c\n" ); -} - -void LogPathTest::testInitListInvalidSlash( ) -{ - T_LogPath lp{ "a" , "b" , "c/" }; - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c/" ); -} - -void LogPathTest::testInitListInvalidEmpty( ) -{ - T_LogPath lp{ "a" , "b" , "" }; - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testFromStringEmpty( ) -{ - T_LogPath lp( T_LogPath::FromString( "" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -void LogPathTest::testFromStringSlash( ) -{ - T_LogPath lp( T_LogPath::FromString( "/" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -void LogPathTest::testFromStringSlashes( ) -{ - T_LogPath lp( T_LogPath::FromString( "/////" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , lp.size( ) ); -} - -void LogPathTest::testFromStringValid( ) -{ - T_LogPath lp( T_LogPath::FromString( "a/b/c" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -void LogPathTest::testFromStringValidSlashes( ) -{ - T_LogPath lp( T_LogPath::FromString( "a//b////c" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -void LogPathTest::testFromStringValidInitialSlash( ) -{ - T_LogPath lp( T_LogPath::FromString( "/a/b/c" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -void LogPathTest::testFromStringValidTrailingSlash( ) -{ - T_LogPath lp( T_LogPath::FromString( "a/b/c/" ) ); - CPPUNIT_ASSERT( lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -void LogPathTest::testFromStringInvalid( ) -{ - T_LogPath lp( T_LogPath::FromString( "a/b\n/c" ) ); - CPPUNIT_ASSERT( !lp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , lp.size( ) ); - CPPUNIT_ASSERT( lp[ 0 ] == "a" ); - CPPUNIT_ASSERT( lp[ 1 ] == "b\n" ); - CPPUNIT_ASSERT( lp[ 2 ] == "c" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testSwap( ) -{ - T_LogPath lp1{ "a" }; - T_LogPath lp2{ "b" , "c" }; - - RPC_String p[] = { - &lp1[ 0 ] , &lp2[ 0 ] , &lp2[ 1 ] - }; - - swap( lp1 , lp2 ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , lp1.size( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , lp2.size( ) ); - CPPUNIT_ASSERT_EQUAL( p[ 0 ] , &lp2[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( p[ 1 ] , &lp1[ 0 ] ); - CPPUNIT_ASSERT_EQUAL( p[ 2 ] , &lp1[ 1 ] ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testParentEmpty( ) -{ - T_LogPath lp; - T_LogPath plp( lp.parent( ) ); - CPPUNIT_ASSERT( plp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , plp.size( ) ); -} - -void LogPathTest::testParentOne( ) -{ - T_LogPath lp{ "a" }; - T_LogPath plp( lp.parent( ) ); - CPPUNIT_ASSERT( plp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , plp.size( ) ); -} - -void LogPathTest::testParentValid( ) -{ - T_LogPath lp{ "a" , "b" }; - T_LogPath plp( lp.parent( ) ); - CPPUNIT_ASSERT( plp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , plp.size( ) ); - CPPUNIT_ASSERT( plp[ 0 ] == "a" ); -} - -void LogPathTest::testParentInvalidChild( ) -{ - T_LogPath lp{ "a" , "b/" }; - T_LogPath plp( lp.parent( ) ); - CPPUNIT_ASSERT( plp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , plp.size( ) ); - CPPUNIT_ASSERT( plp[ 0 ] == "a" ); -} - -void LogPathTest::testParentInvalid( ) -{ - T_LogPath lp{ "a/" , "b" }; - T_LogPath plp( lp.parent( ) ); - CPPUNIT_ASSERT( !plp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , plp.size( ) ); - CPPUNIT_ASSERT( plp[ 0 ] == "a/" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testChildValid( ) -{ - T_LogPath lp{ "a" }; - T_LogPath clp( lp.child( "b" ) ); - - CPPUNIT_ASSERT( clp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , clp.size( ) ); - CPPUNIT_ASSERT( clp[ 0 ] == "a" ); - CPPUNIT_ASSERT( clp[ 1 ] == "b" ); -} - -void LogPathTest::testChildInvalidName( ) -{ - T_LogPath lp{ "a" }; - T_LogPath clp( lp.child( "b\n" ) ); - - CPPUNIT_ASSERT( !clp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , clp.size( ) ); - CPPUNIT_ASSERT( clp[ 0 ] == "a" ); - CPPUNIT_ASSERT( clp[ 1 ] == "b\n" ); -} - -void LogPathTest::testChildInvalidParent( ) -{ - T_LogPath lp{ "a\n" }; - T_LogPath clp( lp.child( "b" ) ); - - CPPUNIT_ASSERT( !clp.isValid( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , clp.size( ) ); - CPPUNIT_ASSERT( clp[ 0 ] == "a\n" ); - CPPUNIT_ASSERT( clp[ 1 ] == "b" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testToStringEmpty( ) -{ - T_LogPath lp; - CPPUNIT_ASSERT( lp.toString( ) == "/" ); -} - -void LogPathTest::testToStringValid( ) -{ - T_LogPath lp{ "a" , "b" , "c" }; - CPPUNIT_ASSERT( lp.toString( ) == "/a/b/c" ); -} - -void LogPathTest::testToStringInvalidSlash( ) -{ - T_LogPath lp{ "a" , "/b" , "c" }; - CPPUNIT_ASSERT( lp.toString( ) == "/a//b/c" ); -} - -void LogPathTest::testToStringInvalidControl( ) -{ - T_LogPath lp{ "a" , "b\n" , "c" }; - CPPUNIT_ASSERT( lp.toString( ) == "/a/b\n/c" ); -} - -void LogPathTest::testToStringInvalidEmpty( ) -{ - T_LogPath lp{ "a" , "" , "c" }; - CPPUNIT_ASSERT( lp.toString( ) == "/a//c" ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testIsParentYes( ) -{ - T_LogPath gc{ "a" , "b" }; - T_LogPath c{ "a" }; - T_LogPath p; - - CPPUNIT_ASSERT( p.isParentOf( c ) ); - CPPUNIT_ASSERT( c.isParentOf( gc ) ); - - CPPUNIT_ASSERT( c.isChildOf( p ) ); - CPPUNIT_ASSERT( gc.isChildOf( c ) ); -} - -void LogPathTest::testIsParentNo( ) -{ - T_LogPath p1{ "a" , "b" , "c" }; - T_LogPath p2{ "a" , "b" , "d" , "e" }; - CPPUNIT_ASSERT( !p1.isParentOf( p2 ) ); - CPPUNIT_ASSERT( !p2.isParentOf( p1 ) ); - CPPUNIT_ASSERT( !p1.isChildOf( p2 ) ); - CPPUNIT_ASSERT( !p2.isChildOf( p1 ) ); -} - -void LogPathTest::testIsParentYesInvalidParent( ) -{ - T_LogPath p1{ "a\n" }; - T_LogPath p2{ "a\n" , "b" }; - CPPUNIT_ASSERT( p1.isParentOf( p2 ) ); - CPPUNIT_ASSERT( p2.isChildOf( p1 ) ); -} - -void LogPathTest::testIsParentYesInvalidChild( ) -{ - T_LogPath p1{ "a" }; - T_LogPath p2{ "a" , "b\n" }; - CPPUNIT_ASSERT( p1.isParentOf( p2 ) ); - CPPUNIT_ASSERT( p2.isChildOf( p1 ) ); -} - -void LogPathTest::testIsParentNoInvalidParent( ) -{ - T_LogPath p1{ "b\n" }; - T_LogPath p2{ "c" , "b" }; - CPPUNIT_ASSERT( !p1.isParentOf( p2 ) ); - CPPUNIT_ASSERT( !p2.isParentOf( p1 ) ); - CPPUNIT_ASSERT( !p1.isChildOf( p2 ) ); - CPPUNIT_ASSERT( !p2.isChildOf( p1 ) ); -} - -void LogPathTest::testIsParentNoInvalidChild( ) -{ - T_LogPath p1{ "b" }; - T_LogPath p2{ "c" , "b\n" }; - CPPUNIT_ASSERT( !p1.isParentOf( p2 ) ); - CPPUNIT_ASSERT( !p2.isParentOf( p1 ) ); - CPPUNIT_ASSERT( !p1.isChildOf( p2 ) ); - CPPUNIT_ASSERT( !p2.isChildOf( p1 ) ); -} - -/*----------------------------------------------------------------------------*/ - -void LogPathTest::testEquals( ) -{ - T_LogPath p1{ "a" }; - T_LogPath p2( p1 ); - T_LogPath p3{ "b" , "c" }; - T_LogPath p4{ "d" }; - CPPUNIT_ASSERT( p1 == p1 ); - CPPUNIT_ASSERT( p1 == p2 ); - CPPUNIT_ASSERT( !( p1 == p3 ) ); - CPPUNIT_ASSERT( !( p1 == p4 ) ); -} - -void LogPathTest::testNotEquals( ) -{ - T_LogPath p1{ "a" }; - T_LogPath p2( p1 ); - T_LogPath p3{ "b" , "c" }; - T_LogPath p4{ "d" }; - CPPUNIT_ASSERT( !( p1 != p1 ) ); - CPPUNIT_ASSERT( !( p1 != p2 ) ); - CPPUNIT_ASSERT( p1 != p3 ); - CPPUNIT_ASSERT( p1 != p4 ); -} - diff --git a/tests/ring-buffer.cc b/tests/ring-buffer.cc index 3733ad8..cc5ce01 100644 --- a/tests/ring-buffer.cc +++ b/tests/ring-buffer.cc @@ -1,6 +1,6 @@ -#include +#include #include -using namespace lw; +using namespace ebcl; class RingBufferTest : public CppUnit::TestFixture diff --git a/tests/run-test.cc b/tests/run-test.cc index 1e01f5f..7de4179 100644 --- a/tests/run-test.cc +++ b/tests/run-test.cc @@ -2,7 +2,7 @@ #include #include -int main( int argc , char * argv[] ) +int main( int , char *[] ) { CppUnit::TextTestRunner runner; runner.addTest( CppUnit::TestFactoryRegistry::getRegistry( ) diff --git a/tests/srd-bin-reader.cc b/tests/srd-bin-reader.cc index 2062c90..9394f81 100644 --- a/tests/srd-bin-reader.cc +++ b/tests/srd-bin-reader.cc @@ -1,7 +1,7 @@ -#include -#include +#include +#include #include -using namespace lw; +using namespace ebcl; #define V1PROLOGUE_ \ diff --git a/tests/srd-bin-writer.cc b/tests/srd-bin-writer.cc index 60759a1..d5d66df 100644 --- a/tests/srd-bin-writer.cc +++ b/tests/srd-bin-writer.cc @@ -1,7 +1,7 @@ -#include -#include +#include +#include #include -using namespace lw; +using namespace ebcl; class SRDBinWriterTest : public CppUnit::TestFixture diff --git a/tests/srd-lexer.cc b/tests/srd-lexer.cc index 4b956c6..aef548f 100644 --- a/tests/srd-lexer.cc +++ b/tests/srd-lexer.cc @@ -1,6 +1,6 @@ -#include +#include #include -using namespace lw; +using namespace ebcl; class SRDLexerTest : public CppUnit::TestFixture diff --git a/tests/srd-mem-target.cc b/tests/srd-mem-target.cc index 9a144b7..17930c5 100644 --- a/tests/srd-mem-target.cc +++ b/tests/srd-mem-target.cc @@ -1,6 +1,6 @@ -#include +#include #include -using namespace lw; +using namespace ebcl; /* - SRDMemTargetTest ---------------------------------------------------{{{-*/ class SRDMemTargetTest : public CppUnit::TestFixture diff --git a/tests/srd-parser-cfg.cc b/tests/srd-parser-cfg.cc index 81a8d1a..fd10543 100644 --- a/tests/srd-parser-cfg.cc +++ b/tests/srd-parser-cfg.cc @@ -1,6 +1,6 @@ -#include +#include #include -using namespace lw; +using namespace ebcl; class SRDParserConfigTest : public CppUnit::TestFixture diff --git a/tests/srd-parser-defs.cc b/tests/srd-parser-defs.cc index 708a3a8..6e9e678 100644 --- a/tests/srd-parser-defs.cc +++ b/tests/srd-parser-defs.cc @@ -1,6 +1,6 @@ -#include +#include #include -using namespace lw; +using namespace ebcl; class SRDInputItemTest : public CppUnit::TestFixture diff --git a/tests/srd-parser.cc b/tests/srd-parser.cc index b078e39..a321e2b 100644 --- a/tests/srd-parser.cc +++ b/tests/srd-parser.cc @@ -1,7 +1,7 @@ -#include -#include +#include +#include #include -using namespace lw; +using namespace ebcl; class SRDParserTest : public CppUnit::TestFixture @@ -302,7 +302,7 @@ T_SRDParserDefs SRDParserTest::makeOLBCDefs( ) void SRDParserTest::testTokenTypes( ) { using F_InitRule = std::function< void( T_SRDContext& ) >; - using namespace lw::SRD; + using namespace ebcl::SRD; const F_InitRule rules[] = { []( T_SRDContext& c ) { c << ( Rule() << Word( ) ); } , []( T_SRDContext& c ) { c << ( Rule() << String( ) ); } , diff --git a/tests/srd-preproc-cmd-arithmetic.cc b/tests/srd-preproc-cmd-arithmetic.cc deleted file mode 100644 index 8624203..0000000 --- a/tests/srd-preproc-cmd-arithmetic.cc +++ /dev/null @@ -1,877 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdArithmeticTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdArithmeticTest ); - - CPPUNIT_TEST( testAddNoArgs ); - CPPUNIT_TEST( testAddOneArg ); - CPPUNIT_TEST( testAddIntInt ); - CPPUNIT_TEST( testAddIntLong ); - CPPUNIT_TEST( testAddLongInt ); - CPPUNIT_TEST( testAddLongLong ); - CPPUNIT_TEST( testAddIntFloat ); - CPPUNIT_TEST( testAddLongFloat ); - CPPUNIT_TEST( testAddFloatInt ); - CPPUNIT_TEST( testAddFloatLong ); - CPPUNIT_TEST( testAddFloatFloat ); - CPPUNIT_TEST( testAddManyInt ); - CPPUNIT_TEST( testAddManyFloat ); - CPPUNIT_TEST( testAddManyWithError ); - - CPPUNIT_TEST( testSubNoArgs ); - CPPUNIT_TEST( testSubOneArg ); - CPPUNIT_TEST( testSubIntInt ); - CPPUNIT_TEST( testSubIntLong ); - CPPUNIT_TEST( testSubLongInt ); - CPPUNIT_TEST( testSubLongLong ); - CPPUNIT_TEST( testSubIntFloat ); - CPPUNIT_TEST( testSubLongFloat ); - CPPUNIT_TEST( testSubFloatInt ); - CPPUNIT_TEST( testSubFloatLong ); - CPPUNIT_TEST( testSubFloatFloat ); - CPPUNIT_TEST( testSubManyInt ); - CPPUNIT_TEST( testSubManyFloat ); - CPPUNIT_TEST( testSubManyWithError ); - - CPPUNIT_TEST( testMulNoArgs ); - CPPUNIT_TEST( testMulOneArg ); - CPPUNIT_TEST( testMulIntInt ); - CPPUNIT_TEST( testMulIntLong ); - CPPUNIT_TEST( testMulLongInt ); - CPPUNIT_TEST( testMulLongLong ); - CPPUNIT_TEST( testMulIntFloat ); - CPPUNIT_TEST( testMulLongFloat ); - CPPUNIT_TEST( testMulFloatInt ); - CPPUNIT_TEST( testMulFloatLong ); - CPPUNIT_TEST( testMulFloatFloat ); - CPPUNIT_TEST( testMulManyInt ); - CPPUNIT_TEST( testMulManyFloat ); - CPPUNIT_TEST( testMulManyWithError ); - - CPPUNIT_TEST( testDivNoArgs ); - CPPUNIT_TEST( testDivOneArg ); - CPPUNIT_TEST( testDivIntInt ); - CPPUNIT_TEST( testDivIntLong ); - CPPUNIT_TEST( testDivLongInt ); - CPPUNIT_TEST( testDivLongLong ); - CPPUNIT_TEST( testDivIntFloat ); - CPPUNIT_TEST( testDivLongFloat ); - CPPUNIT_TEST( testDivFloatInt ); - CPPUNIT_TEST( testDivFloatLong ); - CPPUNIT_TEST( testDivFloatFloat ); - CPPUNIT_TEST( testDivIntZero ); - CPPUNIT_TEST( testDivFloatZero ); - CPPUNIT_TEST( testDivManyInt ); - CPPUNIT_TEST( testDivManyFloat ); - CPPUNIT_TEST( testDivManyWithError ); - - CPPUNIT_TEST( testModNoArgs ); - CPPUNIT_TEST( testModOneArg ); - CPPUNIT_TEST( testModIntInt ); - CPPUNIT_TEST( testModIntLong ); - CPPUNIT_TEST( testModLongInt ); - CPPUNIT_TEST( testModLongLong ); - CPPUNIT_TEST( testModIntFloat ); - CPPUNIT_TEST( testModLongFloat ); - CPPUNIT_TEST( testModFloatInt ); - CPPUNIT_TEST( testModFloatLong ); - CPPUNIT_TEST( testModFloatFloat ); - CPPUNIT_TEST( testModIntZero ); - CPPUNIT_TEST( testModFloatZero ); - CPPUNIT_TEST( testModManyInt ); - CPPUNIT_TEST( testModManyFloat ); - CPPUNIT_TEST( testModManyWithError ); - - CPPUNIT_TEST( testNegNoArgs ); - CPPUNIT_TEST( testNegTooManyArgs ); - CPPUNIT_TEST( testNegBadArg ); - CPPUNIT_TEST( testNegInt ); - CPPUNIT_TEST( testNegLong ); - CPPUNIT_TEST( testNegReal ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testAddNoArgs( ); - void testAddOneArg( ); - void testAddIntInt( ); - void testAddIntLong( ); - void testAddLongInt( ); - void testAddLongLong( ); - void testAddIntFloat( ); - void testAddLongFloat( ); - void testAddFloatInt( ); - void testAddFloatLong( ); - void testAddFloatFloat( ); - void testAddManyInt( ); - void testAddManyFloat( ); - void testAddManyWithError( ); - - void testSubNoArgs( ); - void testSubOneArg( ); - void testSubIntInt( ); - void testSubIntLong( ); - void testSubLongInt( ); - void testSubLongLong( ); - void testSubIntFloat( ); - void testSubLongFloat( ); - void testSubFloatInt( ); - void testSubFloatLong( ); - void testSubFloatFloat( ); - void testSubManyInt( ); - void testSubManyFloat( ); - void testSubManyWithError( ); - - void testMulNoArgs( ); - void testMulOneArg( ); - void testMulIntInt( ); - void testMulIntLong( ); - void testMulLongInt( ); - void testMulLongLong( ); - void testMulIntFloat( ); - void testMulLongFloat( ); - void testMulFloatInt( ); - void testMulFloatLong( ); - void testMulFloatFloat( ); - void testMulManyInt( ); - void testMulManyFloat( ); - void testMulManyWithError( ); - - void testDivNoArgs( ); - void testDivOneArg( ); - void testDivIntInt( ); - void testDivIntLong( ); - void testDivLongInt( ); - void testDivLongLong( ); - void testDivIntFloat( ); - void testDivLongFloat( ); - void testDivFloatInt( ); - void testDivFloatLong( ); - void testDivFloatFloat( ); - void testDivIntZero( ); - void testDivFloatZero( ); - void testDivManyInt( ); - void testDivManyFloat( ); - void testDivManyWithError( ); - - void testModNoArgs( ); - void testModOneArg( ); - void testModIntInt( ); - void testModIntLong( ); - void testModLongInt( ); - void testModLongLong( ); - void testModIntFloat( ); - void testModLongFloat( ); - void testModFloatInt( ); - void testModFloatLong( ); - void testModFloatFloat( ); - void testModIntZero( ); - void testModFloatZero( ); - void testModManyInt( ); - void testModManyFloat( ); - void testModManyWithError( ); - - void testNegNoArgs( ); - void testNegTooManyArgs( ); - void testNegBadArg( ); - void testNegInt( ); - void testNegLong( ); - void testNegReal( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdArithmeticTest ); - -/*----------------------------------------------------------------------------*/ - -#define M_MKTEST_( OP , A1 , A2 ) \ - "( -set out ( -" OP " " A1 " " A2 " ) )\n" \ - "( -type-of $out )\n" \ - "( -if ( -eq ( -type-of $out ) long ) ( (-to-best-integer $out) ) ($out) )" - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdArithmeticTest::testAddNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -add )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddOneArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -add 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , "1" , "1" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 2" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddIntLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , "1" , "12123456789" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12123456790" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddLongInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , "12123456789" , "1" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12123456790" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddLongLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , "12123456789" , "( -to-long 1 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12123456790" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddIntFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , "1" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1.5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddLongFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , "( -to-long 1 )" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1.5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddFloatInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , ".5" , "1" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1.5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddFloatLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , ".5" , "( -to-long 1 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1.5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddFloatFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "add" , ".5" , "1.5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 2.0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddManyInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -add 1 2 3 4 5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "15" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddManyFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -add 1 .5 .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1.75" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testAddManyWithError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -add 1 ( ) .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer or real number expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "1.25" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdArithmeticTest::testSubNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -sub )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubOneArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -sub 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , "1" , "1" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubIntLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , "1" , "12123456789" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long -12123456788" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubLongInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , "12123456789" , "1" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12123456788" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubLongLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , "12123456789" , "( -to-long 1 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12123456788" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubIntFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , "1" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real .5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubLongFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , "( -to-long 1 )" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real .5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubFloatInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , ".5" , "1" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real -.5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubFloatLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , ".5" , "( -to-long 1 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real -.5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubFloatFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "sub" , ".5" , "1.5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real -1.0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubManyInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -sub 20 1 2 3 4 5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubManyFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -sub 1 .5 .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( ".25" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testSubManyWithError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -sub 1 ( ) .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer or real number expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( ".75" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdArithmeticTest::testMulNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mul )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulOneArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mul 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , "2" , "3" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 6" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulIntLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , "2" , "6000000000" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12000000000" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulLongInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , "6000000000" , "2" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12000000000" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulLongLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , "6000000000" , "( -to-long 2 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 12000000000" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulIntFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , "2" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulLongFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , "( -to-long 2 )" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulFloatInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , ".5" , "2" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulFloatLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , ".5" , "( -to-long 2 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulFloatFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mul" , ".5" , "1.5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real .75" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulManyInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mul 2 3 4 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "24" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulManyFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mul 2. .5 .1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( ".1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testMulManyWithError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mul 2 ( ) .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer or real number expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( ".5" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdArithmeticTest::testDivNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivOneArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "4" , "2" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 2" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivIntLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "200" , "( -to-long 10 )" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 20" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivLongInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "12000000000" , "2" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 6000000000" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivLongLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "12000000000" , "6000000000" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 2" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivIntFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "2" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 4." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivLongFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "6000000000" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 12e9" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivFloatInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , ".5" , "2" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real .25" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivFloatLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "12e9" , "6000000000" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 2." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivFloatFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "div" , "1.5" , ".5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 3." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivIntZero( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div 10 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "non-zero argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "10" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivFloatZero( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div 2. 0. )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "non-zero argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "2." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivManyInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div 20 2 5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "2" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivManyFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div 2. .5 4. )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testDivManyWithError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -div 2 ( ) .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer or real number expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "8." , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdArithmeticTest::testModNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModOneArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "4" , "3" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModIntLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "20" , "6000000000" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 20" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModLongInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "6000000000" , "7" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int 1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModLongLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "12000000000" , "7000000000" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long 5000000000" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModIntFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "2" , "1.5" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real .5" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModLongFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "6000000000" , "1e10" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 6e9" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModFloatInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "3.0" , "2" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 1." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModFloatLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "12e9" , "7000000000" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real 5e9" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModFloatFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( M_MKTEST_( "mod" , "1.5" , ".6" ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real .3" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModIntZero( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod 10 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "non-zero argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "10" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModFloatZero( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod 2. 0. )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "non-zero argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "2." , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModManyInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod 23 5 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModManyFloat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod 2. .6 .15 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( ".05" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testModManyWithError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -mod 2 ( ) .25 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer or real number expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "0." , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdArithmeticTest::testNegNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -neg )" , errors ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); -} - -void SRDPreprocCmdArithmeticTest::testNegTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -neg 1 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "-1" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testNegBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -neg nope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer or real argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testNegInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -neg 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-12" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testNegLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -neg 12000000000 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-12000000000" , output ) ); -} - -void SRDPreprocCmdArithmeticTest::testNegReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -neg -1.2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1.2" , output ) ); -} - diff --git a/tests/srd-preproc-cmd-casts.cc b/tests/srd-preproc-cmd-casts.cc deleted file mode 100644 index dc02135..0000000 --- a/tests/srd-preproc-cmd-casts.cc +++ /dev/null @@ -1,1100 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdCastsTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdCastsTest ); - - CPPUNIT_TEST( testToStringEmpty ); - CPPUNIT_TEST( testToStringString ); - CPPUNIT_TEST( testToStringWord ); - CPPUNIT_TEST( testToStringInt ); - CPPUNIT_TEST( testToStringLong ); - CPPUNIT_TEST( testToStringReal ); - CPPUNIT_TEST( testToStringVar ); - CPPUNIT_TEST( testToStringList ); - CPPUNIT_TEST( testToStringBinary ); - CPPUNIT_TEST( testToStringBinaryInvalid ); - CPPUNIT_TEST( testToStringMultiple ); - - CPPUNIT_TEST( testToWordEmpty ); - CPPUNIT_TEST( testToWordStringOk ); - CPPUNIT_TEST( testToWordStringBad ); - CPPUNIT_TEST( testToWordWord ); - CPPUNIT_TEST( testToWordInt ); - CPPUNIT_TEST( testToWordLong ); - CPPUNIT_TEST( testToWordReal ); - CPPUNIT_TEST( testToWordVar ); - CPPUNIT_TEST( testToWordList ); - CPPUNIT_TEST( testToWordMultiple ); - - CPPUNIT_TEST( testToIntEmpty ); - CPPUNIT_TEST( testToIntStringOk ); - CPPUNIT_TEST( testToIntStringBad ); - CPPUNIT_TEST( testToIntWord ); - CPPUNIT_TEST( testToIntInt ); - CPPUNIT_TEST( testToIntLongOk ); - CPPUNIT_TEST( testToIntLongBad ); - CPPUNIT_TEST( testToIntReal ); - CPPUNIT_TEST( testToIntVar ); - CPPUNIT_TEST( testToIntList ); - CPPUNIT_TEST( testToIntMultiple ); - - CPPUNIT_TEST( testToLongEmpty ); - CPPUNIT_TEST( testToLongStringOk ); - CPPUNIT_TEST( testToLongStringBad ); - CPPUNIT_TEST( testToLongWord ); - CPPUNIT_TEST( testToLongInt ); - CPPUNIT_TEST( testToLongLong ); - CPPUNIT_TEST( testToLongReal ); - CPPUNIT_TEST( testToLongVar ); - CPPUNIT_TEST( testToLongList ); - CPPUNIT_TEST( testToLongMultiple ); - - CPPUNIT_TEST( testToBestIntEmpty ); - CPPUNIT_TEST( testToBestIntString32 ); - CPPUNIT_TEST( testToBestIntString64 ); - CPPUNIT_TEST( testToBestIntStringBad ); - CPPUNIT_TEST( testToBestIntWord ); - CPPUNIT_TEST( testToBestIntInt ); - CPPUNIT_TEST( testToBestIntLong32 ); - CPPUNIT_TEST( testToBestIntLong64 ); - CPPUNIT_TEST( testToBestIntReal32 ); - CPPUNIT_TEST( testToBestIntReal64 ); - CPPUNIT_TEST( testToBestIntVar ); - CPPUNIT_TEST( testToBestIntList ); - CPPUNIT_TEST( testToBestIntMultiple ); - - CPPUNIT_TEST( testToRealEmpty ); - CPPUNIT_TEST( testToRealStringOk ); - CPPUNIT_TEST( testToRealStringBad ); - CPPUNIT_TEST( testToRealWord ); - CPPUNIT_TEST( testToRealInt ); - CPPUNIT_TEST( testToRealLong ); - CPPUNIT_TEST( testToRealReal ); - CPPUNIT_TEST( testToRealVar ); - CPPUNIT_TEST( testToRealList ); - CPPUNIT_TEST( testToRealMultiple ); - - CPPUNIT_TEST( testToVarEmpty ); - CPPUNIT_TEST( testToVarStringOk ); - CPPUNIT_TEST( testToVarStringOkWithDollar ); - CPPUNIT_TEST( testToVarStringBadWord ); - CPPUNIT_TEST( testToVarStringBadVarName ); - CPPUNIT_TEST( testToVarWordOk ); - CPPUNIT_TEST( testToVarWordBad ); - CPPUNIT_TEST( testToVarInt ); - CPPUNIT_TEST( testToVarLong ); - CPPUNIT_TEST( testToVarReal ); - CPPUNIT_TEST( testToVarVar ); - CPPUNIT_TEST( testToVarList ); - CPPUNIT_TEST( testToVarMultiple ); - - CPPUNIT_TEST( testToListEmpty ); - CPPUNIT_TEST( testToListString ); - CPPUNIT_TEST( testToListStringEmpty ); - CPPUNIT_TEST( testToListWord ); - CPPUNIT_TEST( testToListBinary ); - CPPUNIT_TEST( testToListBinaryEmpty ); - CPPUNIT_TEST( testToListList ); - CPPUNIT_TEST( testToListListEmpty ); - CPPUNIT_TEST( testToListOtherTypes ); - - CPPUNIT_TEST( testToSourceEmpty ); - CPPUNIT_TEST( testToSourceWord ); - CPPUNIT_TEST( testToSourceString ); - CPPUNIT_TEST( testToSourceInt ); - CPPUNIT_TEST( testToSourceLong ); - CPPUNIT_TEST( testToSourceReal ); - CPPUNIT_TEST( testToSourceVar ); - CPPUNIT_TEST( testToSourceList ); - CPPUNIT_TEST( testToSourceMultiple ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testToStringEmpty( ); - void testToStringString( ); - void testToStringWord( ); - void testToStringInt( ); - void testToStringLong( ); - void testToStringReal( ); - void testToStringVar( ); - void testToStringList( ); - void testToStringBinary( ); - void testToStringBinaryInvalid( ); - void testToStringMultiple( ); - - void testToWordEmpty( ); - void testToWordStringOk( ); - void testToWordStringBad( ); - void testToWordWord( ); - void testToWordInt( ); - void testToWordLong( ); - void testToWordReal( ); - void testToWordVar( ); - void testToWordList( ); - void testToWordMultiple( ); - - void testToIntEmpty( ); - void testToIntStringOk( ); - void testToIntStringBad( ); - void testToIntWord( ); - void testToIntInt( ); - void testToIntLongOk( ); - void testToIntLongBad( ); - void testToIntReal( ); - void testToIntVar( ); - void testToIntList( ); - void testToIntMultiple( ); - - void testToLongEmpty( ); - void testToLongStringOk( ); - void testToLongStringBad( ); - void testToLongWord( ); - void testToLongInt( ); - void testToLongLong( ); - void testToLongReal( ); - void testToLongVar( ); - void testToLongList( ); - void testToLongMultiple( ); - - void testToBestIntEmpty( ); - void testToBestIntString32( ); - void testToBestIntString64( ); - void testToBestIntStringBad( ); - void testToBestIntWord( ); - void testToBestIntInt( ); - void testToBestIntLong32( ); - void testToBestIntLong64( ); - void testToBestIntReal32( ); - void testToBestIntReal64( ); - void testToBestIntVar( ); - void testToBestIntList( ); - void testToBestIntMultiple( ); - - void testToRealEmpty( ); - void testToRealStringOk( ); - void testToRealStringBad( ); - void testToRealWord( ); - void testToRealInt( ); - void testToRealLong( ); - void testToRealReal( ); - void testToRealVar( ); - void testToRealList( ); - void testToRealMultiple( ); - - void testToVarEmpty( ); - void testToVarStringOk( ); - void testToVarStringOkWithDollar( ); - void testToVarStringBadWord( ); - void testToVarStringBadVarName( ); - void testToVarWordOk( ); - void testToVarWordBad( ); - void testToVarInt( ); - void testToVarLong( ); - void testToVarReal( ); - void testToVarVar( ); - void testToVarList( ); - void testToVarMultiple( ); - - void testToListEmpty( ); - void testToListString( ); - void testToListStringEmpty( ); - void testToListWord( ); - void testToListBinary( ); - void testToListBinaryEmpty( ); - void testToListList( ); - void testToListListEmpty( ); - void testToListOtherTypes( ); - - void testToSourceEmpty( ); - void testToSourceWord( ); - void testToSourceString( ); - void testToSourceInt( ); - void testToSourceLong( ); - void testToSourceReal( ); - void testToSourceVar( ); - void testToSourceList( ); - void testToSourceMultiple( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdCastsTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToStringEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string \"a string\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"a string\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string word )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"word\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"1\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string 12123456789 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"12123456789\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string 0.5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"0.5\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string ( -raw $a ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"$a\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string [ 4c 4f 4c ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"LOL\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringBinaryInvalid( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string [ 80 4c 4f 4c e5 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid UTF-8 data" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToStringMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-string \"a\" b ( ) ( -raw $c ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "\"a\" \"b\" \"$c\"" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToWordEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordStringOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word \"a-word\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "a-word" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word \"not a word, lol\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid word" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word word )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "word" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word 12123456789 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word 0.5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToWordMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-word ( ) \"a\" ( -raw $b ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "invalid a b" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToIntEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntStringOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer \"123\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "123" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer \"123nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid integer value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer word )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer 123 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "123" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntLongOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer ( -to-long 123 ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "123" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntLongBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer 12345678912 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "value out of range" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "2147483647" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer 0.5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 22 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToIntMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-integer ( ) 1 \"2\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0 1 2" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToLongEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToLongStringOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long \"12345678912\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12345678912" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToLongStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long \"123nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid integer value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , output.size( ) ); - CPPUNIT_ASSERT( output[ 0 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , output[ 0 ].longValue( ) ); -} - -void SRDPreprocCmdCastsTest::testToLongWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long word )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , output.size( ) ); - CPPUNIT_ASSERT( output[ 0 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , output[ 0 ].longValue( ) ); -} - -void SRDPreprocCmdCastsTest::testToLongInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long 123 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , output.size( ) ); - CPPUNIT_ASSERT( output[ 0 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 123 ) , output[ 0 ].longValue( ) ); -} - -void SRDPreprocCmdCastsTest::testToLongLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long 12345678912 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12345678912" , output ) ); -} - - -void SRDPreprocCmdCastsTest::testToLongReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long 1e10 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "10000000000" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToLongVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 19 ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , output.size( ) ); - CPPUNIT_ASSERT( output[ 0 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , output[ 0 ].longValue( ) ); -} - -void SRDPreprocCmdCastsTest::testToLongList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , output.size( ) ); - CPPUNIT_ASSERT( output[ 0 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , output[ 0 ].longValue( ) ); -} - -void SRDPreprocCmdCastsTest::testToLongMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-long ( ) 12345678912 \"12123456789\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT_EQUAL( 3u , output.size( ) ); - CPPUNIT_ASSERT( output[ 0 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 0 ) , output[ 0 ].longValue( ) ); - CPPUNIT_ASSERT( output[ 1 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 12345678912L ) , output[ 1 ].longValue( ) ); - CPPUNIT_ASSERT( output[ 2 ].type( ) == E_SRDTokenType::LONG ); - CPPUNIT_ASSERT_EQUAL( int64_t( 12123456789L ) , output[ 2 ].longValue( ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToBestIntEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntString32( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer \"123456\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "123456" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntString64( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer \"12345678912\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12345678912" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer \"123nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid integer value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer nope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer 123 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "123" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntLong32( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer ( -to-long 123 ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "123" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntLong64( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer 12345678912 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12345678912" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntReal32( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer 12.3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntReal64( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer 1e10 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "10000000000" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 27 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToBestIntMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-best-integer ( ) \"123\" 456 78912345678 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0 123 456 78912345678" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToRealEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealStringOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real \"-12e-3\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-0.012" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real \"nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid real value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "0." , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real nope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "0." , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12.0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real 12345678912 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "12345678912.0" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real 1234567891.2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1234567891.2" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 19 ); - CPPUNIT_ASSERT( check( "0." , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "0." , output ) ); -} - -void SRDPreprocCmdCastsTest::testToRealMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-real ( ) 123 456.5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "0. 123.0 456.5" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToVarEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarStringOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable \"name\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "$name" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarStringOkWithDollar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable \"$name\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "$name" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarStringBadWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable \"not a word\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid variable name" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarStringBadVarName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable \"-bad\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid variable name" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarWordOk( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable name )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "$name" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarWordBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable -bad )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid variable name" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable 12345678912 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable 1.5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "$x" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToVarMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-variable ( ) \"$x\" y )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unsupported type conversion" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "$invalid $x $y" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToListEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"a\" \"b\" \"c\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListStringEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list \"\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list abc )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"a\" \"b\" \"c\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list [ deadbeef ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "222 173 190 239" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListBinaryEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list [ ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list ( ab c ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "ab c" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListListEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToListOtherTypes( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-list 10 1.2 (-raw $x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "10 1.2 $x" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCastsTest::testToSourceEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source word )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"word\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source \"some\\nstring\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"\\\"some\\\\nstring\\\"\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source 123 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"123\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source 5000000000 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"5000000000\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source 1.2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"1.2\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -to-source (-raw $x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"$x\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-to-source ( word \"string\" 123 5000000000 1.2 (-raw $x) ))" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"( word \\\"string\\\" 123 5000000000 1.2 $x )\"" , output ) ); -} - -void SRDPreprocCmdCastsTest::testToSourceMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-to-source word \"string\" 123 5000000000 1.2 (-raw $x) ( some list ))" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"word \\\"string\\\" 123 5000000000 1.2 $x ( some list )\"" , output ) ); -} diff --git a/tests/srd-preproc-cmd-common.hh b/tests/srd-preproc-cmd-common.hh deleted file mode 100644 index a6990d7..0000000 --- a/tests/srd-preproc-cmd-common.hh +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef TESTS_SRDPREPROCCMDCOMMON_H_ -#define TESTS_SRDPREPROCCMDCOMMON_H_ - -#include -#include -#include -#include -#include -using namespace lw; - -// M_PRINTERR_( index ) - Print an error message -#define M_PRINTERR_( IDX ) \ - do { \ - auto const& _e( errors[ IDX ] ); \ - char err[ _e.error( ).size( ) + 1 ]; \ - err[ sizeof( err ) - 1 ] = 0; \ - memcpy( err , _e.error( ).data( ) , \ - sizeof( err ) - 1 ); \ - printf( "ERR %s l. %u c. %lu\n" , err , \ - _e.location( ).line( ) , \ - _e.location( ).character( ) ); \ - } while ( 0 ) - -// M_CKERR_( index , string , line , character ) - Check an error -#define M_CKERR_( IDX , STR , L , C ) \ - do { \ - auto const& _e( errors[ IDX ] ); \ - CPPUNIT_ASSERT( T_String( STR ) == _e.error( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( L ) , \ - _e.location( ).line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( C ) , \ - _e.location( ).character( ) ); \ - } while ( 0 ) - -namespace { - -void process( char const* input , T_SRDPreprocessor& preproc , T_SRDErrors& errors ) -{ - T_SRDLexer lexer( T_String( "test" ) , errors , preproc ); - preproc.start( errors ); - char const* ptr = input; - while ( *ptr != 0 ) { - lexer.processCharacter( *ptr ++ ); - } - lexer.processEnd( ); -} - -T_SRDList process( char const* input , T_SRDErrors& errors ) -{ - T_SRDMemoryTarget mt( false ); - mt.clearFlushToken( true ); - mt.start( errors ); - - T_SRDPreprocessorConfig emptyConfig; - emptyConfig.addBuiltinCommands( ); - T_SRDPreprocessor pp( emptyConfig , mt ); - process( input , pp , errors ); - mt.end( errors ); - - return mt.list( ); -} - -bool checkMatch( T_SRDList const& expected , T_SRDList const& actual ) -{ - const size_t nExpected( expected.size( ) ); - const size_t nActual( actual.size( ) ); - - bool ok( nExpected == nActual ); - const size_t nCheck( std::min( nExpected , nActual ) ); - for ( size_t i = 0 ; i < nCheck ; i ++ ) { - T_SRDToken const& tExpected( expected[ i ] ); - T_SRDToken const& tActual( actual[ i ] ); - if ( tExpected.type( ) != tActual.type( ) ) { - ok = false; - } else if ( tExpected.stringValue( ) != tActual.stringValue( ) ) { - ok = false; - } - } - return ok; -} - -bool check( char const* expected , T_SRDList const& actual ) -{ - T_SRDMemoryTarget mt( false ); - T_SRDErrors errors; - T_SRDLexer lexer( T_String( "expected" ) , errors , mt ); - mt.start( errors ); - char const* ptr = expected; - while ( *ptr != 0 ) { - lexer.processCharacter( *ptr ++ ); - } - lexer.processEnd( ); - - const bool ok( checkMatch( mt.list( ) , actual ) ); - if ( ok ) { - return true; - } - T_Buffer< char > output; - T_MemoryOutputStream stream{ output }; - lw::SRDWriteAsText( stream , actual ); - stream.write( "" , 1 ); - std::cerr << "\nExpected:\n\t" << expected << "\nActual:\n" << output.data( ) << '\n'; - return false; -} - -} - -#endif // TESTS_SRDPREPROCCMDCOMMON_H_ diff --git a/tests/srd-preproc-cmd-compare.cc b/tests/srd-preproc-cmd-compare.cc deleted file mode 100644 index 8d924e7..0000000 --- a/tests/srd-preproc-cmd-compare.cc +++ /dev/null @@ -1,340 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdCompareTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdCompareTest ); - - CPPUNIT_TEST( testCmpMissingArgs ); - CPPUNIT_TEST( testCmpExtraArgs ); - CPPUNIT_TEST( testCmp ); - - CPPUNIT_TEST( testEqMissingArgs ); - CPPUNIT_TEST( testEqExtraArgs ); - CPPUNIT_TEST( testEq ); - - CPPUNIT_TEST( testNeMissingArgs ); - CPPUNIT_TEST( testNeExtraArgs ); - CPPUNIT_TEST( testNe ); - - CPPUNIT_TEST( testLtMissingArgs ); - CPPUNIT_TEST( testLtExtraArgs ); - CPPUNIT_TEST( testLt ); - - CPPUNIT_TEST( testGtMissingArgs ); - CPPUNIT_TEST( testGtExtraArgs ); - CPPUNIT_TEST( testGt ); - - CPPUNIT_TEST( testLeMissingArgs ); - CPPUNIT_TEST( testLeExtraArgs ); - CPPUNIT_TEST( testLe ); - - CPPUNIT_TEST( testGeMissingArgs ); - CPPUNIT_TEST( testGeExtraArgs ); - CPPUNIT_TEST( testGe ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testCmpMissingArgs( ); - void testCmpExtraArgs( ); - void testCmp( ); - - void testEqMissingArgs( ); - void testEqExtraArgs( ); - void testEq( ); - - void testNeMissingArgs( ); - void testNeExtraArgs( ); - void testNe( ); - - void testLtMissingArgs( ); - void testLtExtraArgs( ); - void testLt( ); - - void testGtMissingArgs( ); - void testGtExtraArgs( ); - void testGt( ); - - void testLeMissingArgs( ); - void testLeExtraArgs( ); - void testLe( ); - - void testGeMissingArgs( ); - void testGeExtraArgs( ); - void testGe( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdCompareTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testCmpMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -cmp )\n( -cmp a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 10 ); - CPPUNIT_ASSERT( check( "0 0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testCmpExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -cmp a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "-1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testCmp( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -cmp a a )\n" - "( -cmp a b )\n" - "( -cmp ((a)) b )\n" - "( -cmp a ((b)) )\n" - "( -cmp ((a)) ((b)) )\n" - "( -cmp ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0 -1 -1 1 -1 0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testEqMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -eq )\n( -eq a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "1 1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testEqExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -eq a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testEq( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -eq a a )\n" - "( -eq a b )\n" - "( -eq ((a)) b )\n" - "( -eq a ((b)) )\n" - "( -eq ((a)) ((b)) )\n" - "( -eq ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 0 0 0 0 1" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testNeMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ne )\n( -ne a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "0 0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testNeExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ne a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testNe( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -ne a a )\n" - "( -ne a b )\n" - "( -ne ((a)) b )\n" - "( -ne a ((b)) )\n" - "( -ne ((a)) ((b)) )\n" - "( -ne ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0 1 1 1 1 0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testLtMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -lt )\n( -lt a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "0 0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testLtExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -lt a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testLt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -lt a a )\n" - "( -lt a b )\n" - "( -lt ((a)) b )\n" - "( -lt a ((b)) )\n" - "( -lt ((a)) ((b)) )\n" - "( -lt ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0 1 1 0 1 0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testGtMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -gt )\n( -gt a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "0 0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testGtExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -gt a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testGt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -gt a a )\n" - "( -gt a b )\n" - "( -gt ((a)) b )\n" - "( -gt a ((b)) )\n" - "( -gt ((a)) ((b)) )\n" - "( -gt ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0 0 0 1 0 0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testLeMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -le )\n( -le a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "1 1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testLeExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -le a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testLe( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -le a a )\n" - "( -le a b )\n" - "( -le ((a)) b )\n" - "( -le a ((b)) )\n" - "( -le ((a)) ((b)) )\n" - "( -le ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 1 1 0 1 1" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCompareTest::testGeMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ge )\n( -ge a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - M_CKERR_( 2 , "not enough arguments" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "1 1" , output ) ); -} - -void SRDPreprocCmdCompareTest::testGeExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ge a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdCompareTest::testGe( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -ge a a )\n" - "( -ge a b )\n" - "( -ge ((a)) b )\n" - "( -ge a ((b)) )\n" - "( -ge ((a)) ((b)) )\n" - "( -ge ((a)) ((a)) )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 0 0 1 0 1" , output ) ); -} diff --git a/tests/srd-preproc-cmd-core.cc b/tests/srd-preproc-cmd-core.cc deleted file mode 100644 index de8826f..0000000 --- a/tests/srd-preproc-cmd-core.cc +++ /dev/null @@ -1,1303 +0,0 @@ -#include "srd-preproc-cmd-common.hh" -#include "srd-preproc-location.hh" - - -class SRDPreprocCmdCoreTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdCoreTest ); - - CPPUNIT_TEST( testRaw ); - CPPUNIT_TEST( testRawEmpty ); - CPPUNIT_TEST( testRawSkipComments ); - CPPUNIT_TEST( testRawUnterminated ); - - CPPUNIT_TEST( testIfMissingArgs ); - CPPUNIT_TEST( testIfExtraArgs ); - CPPUNIT_TEST( testIfBadCondition ); - CPPUNIT_TEST( testIfBadThenBlock ); - CPPUNIT_TEST( testIfBadElseBlock ); - CPPUNIT_TEST( testIfTrueThen ); - CPPUNIT_TEST( testIfFalseThen ); - CPPUNIT_TEST( testIfTrueThenElse ); - CPPUNIT_TEST( testIfFalseThenElse ); - CPPUNIT_TEST( testIfArgSubst ); - CPPUNIT_TEST( testIfThenInnerList ); - CPPUNIT_TEST( testIfElseInnerList ); - - CPPUNIT_TEST( testEvalEmpty ); - CPPUNIT_TEST( testEval ); - CPPUNIT_TEST( testEvalErrors ); - CPPUNIT_TEST( testEvalSkipComments ); - CPPUNIT_TEST( testEvalUnterminated ); - CPPUNIT_TEST( testEvalInnerList ); - CPPUNIT_TEST( testEvalCalls ); - - CPPUNIT_TEST( testScope ); - CPPUNIT_TEST( testScopeValues ); - CPPUNIT_TEST( testScopeInnerList ); - - CPPUNIT_TEST( testClearScopeInstruction ); - CPPUNIT_TEST( testClearScopeBlock ); - CPPUNIT_TEST( testClearScopeInnerList ); - - CPPUNIT_TEST( testTryEmpty ); - CPPUNIT_TEST( testTryNoErrors ); - CPPUNIT_TEST( testTryErrors ); - CPPUNIT_TEST( testTryErrorsChained ); - CPPUNIT_TEST( testTryUnterminated ); - CPPUNIT_TEST( testTryTooManyErrors ); - CPPUNIT_TEST( testTryInnerList ); - - CPPUNIT_TEST( testOutput ); - CPPUNIT_TEST( testOutputErrors ); - - CPPUNIT_TEST( testErrorEmpty ); - CPPUNIT_TEST( testErrorWord ); - CPPUNIT_TEST( testErrorString ); - CPPUNIT_TEST( testErrorVar ); - CPPUNIT_TEST( testErrorInt ); - CPPUNIT_TEST( testErrorLong ); - CPPUNIT_TEST( testErrorReal ); - CPPUNIT_TEST( testErrorList ); - CPPUNIT_TEST( testErrorConcat ); - - CPPUNIT_TEST( testBreakMain ); - CPPUNIT_TEST( testBreakMainList ); - CPPUNIT_TEST( testBreakEvalInput ); - CPPUNIT_TEST( testBreakEvalOutput ); - CPPUNIT_TEST( testBreakFunction ); - CPPUNIT_TEST( testBreakRecursiveFunction ); - CPPUNIT_TEST( testBreakMacro ); - CPPUNIT_TEST( testBreakArgs ); - - CPPUNIT_TEST( testRethrowNothing ); - CPPUNIT_TEST( testRethrowList ); - CPPUNIT_TEST( testRethrowEmptyList ); - CPPUNIT_TEST( testRethrowUnwrapped ); - CPPUNIT_TEST( testRethrowErrorWord ); - CPPUNIT_TEST( testRethrowSourceWord ); - CPPUNIT_TEST( testRethrowDetails ); - CPPUNIT_TEST( testRethrowChained ); - CPPUNIT_TEST( testRethrowChainedDepth ); - - CPPUNIT_TEST( testRethrowNoList ); - CPPUNIT_TEST( testRethrowBadMessage ); - CPPUNIT_TEST( testRethrowNoLocation ); - CPPUNIT_TEST( testRethrowBadLocation ); - CPPUNIT_TEST( testRethrowLocationBadSource ); - CPPUNIT_TEST( testRethrowLocationBadLine ); - CPPUNIT_TEST( testRethrowLocationNegativeLine ); - CPPUNIT_TEST( testRethrowLocationLineTooHigh ); - CPPUNIT_TEST( testRethrowLocationBadChar ); - CPPUNIT_TEST( testRethrowLocationNegativeChar ); - CPPUNIT_TEST( testRethrowChainedBad ); - CPPUNIT_TEST( testRethrowChainedInvalid ); - CPPUNIT_TEST( testRethrowChainedNoLocation ); - CPPUNIT_TEST( testRethrowChainedBadLocation ); - CPPUNIT_TEST( testRethrowChainedNegativeDepth ); - CPPUNIT_TEST( testRethrowChainedDepthTooHigh ); - CPPUNIT_TEST( testRethrowChainedDepthNoLocation ); - CPPUNIT_TEST( testRethrowChainedDepthBadLocation ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testRaw( ); - void testRawEmpty( ); - void testRawSkipComments( ); - void testRawUnterminated( ); - - void testIfMissingArgs( ); - void testIfExtraArgs( ); - void testIfBadCondition( ); - void testIfBadThenBlock( ); - void testIfBadElseBlock( ); - void testIfTrueThen( ); - void testIfFalseThen( ); - void testIfTrueThenElse( ); - void testIfFalseThenElse( ); - void testIfArgSubst( ); - void testIfThenInnerList( ); - void testIfElseInnerList( ); - - void testEvalEmpty( ); - void testEval( ); - void testEvalErrors( ); - void testEvalSkipComments( ); - void testEvalUnterminated( ); - void testEvalInnerList( ); - void testEvalCalls( ); - - void testScope( ); - void testScopeValues( ); - void testScopeInnerList( ); - - void testClearScopeInstruction( ); - void testClearScopeBlock( ); - void testClearScopeInnerList( ); - - void testTryEmpty( ); - void testTryNoErrors( ); - void testTryErrors( ); - void testTryErrorsChained( ); - void testTryUnterminated( ); - void testTryTooManyErrors( ); - void testTryInnerList( ); - - void testOutput( ); - void testOutputErrors( ); - - void testErrorEmpty( ); - void testErrorWord( ); - void testErrorString( ); - void testErrorVar( ); - void testErrorInt( ); - void testErrorLong( ); - void testErrorReal( ); - void testErrorList( ); - void testErrorConcat( ); - - void testBreakMain( ); - void testBreakMainList( ); - void testBreakEvalInput( ); - void testBreakEvalOutput( ); - void testBreakFunction( ); - void testBreakRecursiveFunction( ); - void testBreakMacro( ); - void testBreakArgs( ); - - void testRethrowNothing( ); - void testRethrowList( ); - void testRethrowEmptyList( ); - void testRethrowUnwrapped( ); - void testRethrowErrorWord( ); - void testRethrowSourceWord( ); - void testRethrowDetails( ); - void testRethrowChained( ); - void testRethrowChainedDepth( ); - - void testRethrowNoList( ); - void testRethrowBadMessage( ); - void testRethrowNoLocation( ); - void testRethrowBadLocation( ); - void testRethrowLocationBadSource( ); - void testRethrowLocationBadLine( ); - void testRethrowLocationNegativeLine( ); - void testRethrowLocationLineTooHigh( ); - void testRethrowLocationBadChar( ); - void testRethrowLocationNegativeChar( ); - void testRethrowChainedBad( ); - void testRethrowChainedInvalid( ); - void testRethrowChainedNoLocation( ); - void testRethrowChainedBadLocation( ); - void testRethrowChainedNegativeDepth( ); - void testRethrowChainedDepthTooHigh( ); - void testRethrowChainedDepthNoLocation( ); - void testRethrowChainedDepthBadLocation( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdCoreTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testRaw( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -raw ok $x ( -raw ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "ok $x ( -raw )" , output ) ); - M_CKTOKFULL_( 0 , "test" , 1 , 8 , 0 ); - M_CKTOKFULL_( 1 , "test" , 1 , 11 , 0 ); - M_CKTOKFULL_( 2 , "test" , 1 , 14 , 0 ); - M_CKTOKFULL_( 3 , "test" , 1 , 16 , 0 ); - M_CKTOKFULL_( 4 , "test" , 1 , 21 , 0 ); -} - -void SRDPreprocCmdCoreTest::testRawEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -raw )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRawSkipComments( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -raw { a comment } x # another comment!\n)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); - M_CKTOKFULL_( 0 , "test" , 1 , 22 , 0 ); -} - -void SRDPreprocCmdCoreTest::testRawUnterminated( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -raw\n(\n(" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) ); - M_CKERRFULL_( 0 , "unterminated list" , false , "test" , 1 , 1 , 0 ); - M_CKERRFULL_( 1 , "unterminated list" , false , "test" , 2 , 1 , 0 ); - M_CKERRFULL_( 2 , "unterminated list" , false , "test" , 3 , 1 , 0 ); - CPPUNIT_ASSERT( check( "(())" , output ) ); - M_CKTOKFULL_( 0 , "test" , 2 , 1 , 0 ); - M_CKTOKFULL_( 1 , "test" , 3 , 1 , 0 ); - M_CKTOKFULL_( 2 , "*unexpected end of file*" , 0 , 2 , 0 ); - M_CKTOKFULL_( 3 , "*unexpected end of file*" , 0 , 1 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testIfMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if )\n( -if 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERRFULL_( 0 , "not enough arguments" , false , "test" , 1 , 3 , 0 ); - M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 7 , 0 ); - M_CKERRFULL_( 2 , "not enough arguments" , false , "test" , 2 , 3 , 0 ); - M_CKERRFULL_( 3 , "previous error cause" , true , "test" , 2 , 9 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testIfExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 0 (a) (b) (blah()) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERRFULL_( 0 , "too many arguments" , false , "test" , 1 , 3 , 0 ); - M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 17 , 0 ); - CPPUNIT_ASSERT( check( "b" , output ) ); - M_CKTOKFULL_( 0 , "test" , 1 , 14 , 0 ); -} - -void SRDPreprocCmdCoreTest::testIfBadCondition( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if nope () )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERRFULL_( 0 , "numeric value expected" , false , "test" , 1 , 3 , 0 ); - M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 7 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testIfBadThenBlock( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 1 nope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERRFULL_( 0 , "list expected" , false , "test" , 1 , 3 , 0 ); - M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 9 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testIfBadElseBlock( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 1 (a) nope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERRFULL_( 0 , "list expected" , false , "test" , 1 , 3 , 0 ); - M_CKERRFULL_( 1 , "previous error cause" , true , "test" , 1 , 13 , 0 ); - CPPUNIT_ASSERT( check( "a" , output ) ); -} - -void SRDPreprocCmdCoreTest::testIfTrueThen( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 1 (x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); - M_CKTOKFULL_( 0 , "test" , 1 , 10 , 0 ); -} - -void SRDPreprocCmdCoreTest::testIfFalseThen( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 0 (x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testIfTrueThenElse( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 1 (x) (y) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); - M_CKTOKFULL_( 0 , "test" , 1 , 10 , 0 ); -} - -void SRDPreprocCmdCoreTest::testIfFalseThenElse( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -if 0 (x) (y) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "y" , output ) ); - M_CKTOKFULL_( 0 , "test" , 1 , 14 , 0 ); -} - -void SRDPreprocCmdCoreTest::testIfArgSubst( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x 1 )\n" - "( -if $x (x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); - M_CKTOKFULL_( 0 , "test" , 2 , 11 , 0 ); -} - -void SRDPreprocCmdCoreTest::testIfThenInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -if 1 (-not-a-command) )\n" - "( -if 1 ($x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); - M_CKTOKFULL_( 0 , "test" , 3 , 10 , 0 ); - M_CKTOKFULL_( 1 , "$x" , 0 , 0 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 ); - M_CKTOKFULL_( 2 , "$x" , 0 , 1 , 1 ); - M_CKTOKCHAIN_( 2 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 ); - M_CKTOKFULL_( 3 , "$x" , 0 , 2 , 1 ); - M_CKTOKCHAIN_( 3 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 ); - M_CKTOKFULL_( 4 , "$x" , 0 , 3 , 1 ); - M_CKTOKCHAIN_( 4 , 0 , SUBSTITUTED , "test" , 4 , 10 , 0 ); -} - -void SRDPreprocCmdCoreTest::testIfElseInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -if 0 () (-not-a-command) )\n" - "( -if 0 () ($x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); - M_CKTOKFULL_( 0 , "test" , 3 , 13 , 0 ); - M_CKTOKFULL_( 1 , "$x" , 0 , 0 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 ); - M_CKTOKFULL_( 2 , "$x" , 0 , 1 , 1 ); - M_CKTOKCHAIN_( 2 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 ); - M_CKTOKFULL_( 3 , "$x" , 0 , 2 , 1 ); - M_CKTOKCHAIN_( 3 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 ); - M_CKTOKFULL_( 4 , "$x" , 0 , 3 , 1 ); - M_CKTOKCHAIN_( 4 , 0 , SUBSTITUTED , "test" , 4 , 13 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testEvalEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -eval )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testEval( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set (x y)\n" - "( -raw $y )\n" - "this-is-y\n" - ")\n" - "eval ( -eval $x ) actual $x" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "eval this-is-y actual $y" , output ) ); - M_CKTOKFULL_( 0 , "test" , 5 , 1 , 0 ); - M_CKTOKFULL_( 1 , "$y" , 0 , 0 , 2 ); - M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "$x" , 0 , 0 , 0 ); - M_CKTOKCHAIN_( 1 , 1 , EVALUATED , "test" , 5 , 8 , 0 ); - M_CKTOKFULL_( 2 , "test" , 5 , 19 , 0 ); - M_CKTOKFULL_( 3 , "$x" , 0 , 0 , 1 ); - M_CKTOKCHAIN_( 3 , 0 , SUBSTITUTED , "test" , 5 , 26 , 0 ); -} - -void SRDPreprocCmdCoreTest::testEvalErrors( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x ( -raw $does-not-exist ) )\n" - "( -eval $x )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERRFULL_( 0 , "unknown variable" , false , "$x" , 0 , 0 , 1 ); - M_CKERRCHAIN_( 0 , 0 , EVALUATED , "test" , 2 , 3 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testEvalSkipComments( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -eval (-from-source \"{ a comment } x # another comment!\")\n)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); - M_CKTOKFULL_( 0 , "-from-source" , 1 , 15 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 10 , 0 ); -} - -void SRDPreprocCmdCoreTest::testEvalUnterminated( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -eval\n(\n(" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) ); - M_CKERR_( 0 , "unterminated list" , 1 , 1 ); - M_CKERR_( 1 , "unterminated list" , 2 , 1 ); - M_CKERR_( 2 , "unterminated list" , 3 , 1 ); - CPPUNIT_ASSERT( check( "(())" , output ) ); - M_CKTOKFULL_( 0 , "test" , 2 , 1 , 0 ); - M_CKTOKFULL_( 1 , "test" , 3 , 1 , 0 ); - M_CKTOKFULL_( 2 , "*unexpected end of file*" , 0 , 2 , 0 ); - M_CKTOKFULL_( 3 , "*unexpected end of file*" , 0 , 1 , 0 ); -} - -void SRDPreprocCmdCoreTest::testEvalInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -eval -not-a-command )\n" - "( -eval $x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); -} - -void SRDPreprocCmdCoreTest::testEvalCalls( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set (x y) (-raw (() f1 (-raw $y) f2)) x)\n" - "(-bless x)\n" - "( -eval a $y b ($x) c ($x) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "a x b f1 x f2 c f1 x f2" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testScope( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro dump ( ( ) ( -raw ( ( -raw\n" - "( -is-set x )\n" - "( -is-blessed f )\n" - "( -is-set y )\n" - "( -is-macro m )\n" - "( -is-macro n )\n" - ") ) ) ) )\n" - "( -set x 1 )\n" - "( -set f (()) )\n" - "( -set-macro m ( ( ) ) )\n" - "( -scope\n" - "( -unset x )\n" - "( -bless f )\n" - "( -set y 0 )\n" - "( -unset-macro m )\n" - "( -set-macro n ( ( ) ) )\n" - "(dump)\n" - ")\n" - "(dump)\n" - "" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "( 0 1 1 0 1 ) ( 1 0 0 1 0 )" , output ) ); -} - -void SRDPreprocCmdCoreTest::testScopeValues( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x 1 )\n" - "$x\n" - "( -scope\n" - "( -set x 2 )\n" - "$x\n" - ")\n" - "$x\n" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 2 1" , output ) ); -} - -void SRDPreprocCmdCoreTest::testScopeInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -scope -not-a-command )\n" - "( -scope $x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testClearScopeInstruction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x )\n" - "( -set-macro y ( ( ) ) )\n" - "( -is-set x )\n" - "( -is-macro y )\n" - "( -clear-scope )\n" - "( -is-set x )\n" - "( -is-macro y )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 1 0 0" , output ) ); -} - -void SRDPreprocCmdCoreTest::testClearScopeBlock( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x )\n" - "( -set-macro y ( ( ) ) )\n" - "( -is-set x )\n" - "( -is-macro y )\n" - "( -clear-scope\n" - "( -is-set x )\n" - "( -is-macro y )\n" - ")\n" - "( -is-set x )\n" - "( -is-macro y )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 1 0 0 1 1" , output ) ); -} - -void SRDPreprocCmdCoreTest::testClearScopeInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -clear-scope -not-a-command )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testTryEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-try )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "() ()" , output ) ); -} - -void SRDPreprocCmdCoreTest::testTryNoErrors( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-try 1 2 3)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(1 2 3) ()" , output ) ); -} - -void SRDPreprocCmdCoreTest::testTryErrors( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -try $x 2 $y )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "( 2 ) ( " - "( \"unknown variable\" ( \"test\" 1 8 ) )" - "( \"unknown variable\" ( \"test\" 1 13 ) )" - ")" , output ) ); -} - -void SRDPreprocCmdCoreTest::testTryErrorsChained( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set (f1 f2) (-raw\n" - "(() f1 $x)\n" - "((a)\n" - "f2 $a\n" - "(-if (-gt $a 0) (\n" - "($f2 (-sub $a 1))\n" - ")(\n" - "($f1)\n" - "))\n" - ")\n" - "))\n" - "(-bless f1 f2)\n" - "( -try ($f1) ($f2 5))" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( - "( f1 f2 5 f2 4 f2 3 f2 2 f2 1 f2 0 f1 ) ( " - "( \"unknown variable\"" - "( \"test\" 2 8 )" - "called ( \"test\" 13 9 )" - ")" - "( \"unknown variable\"" - "( \"test\" 2 8 )" - "called ( \"test\" 8 2 )" - "called 4 ( \"test\" 6 2 )" - "called ( \"test\" 13 15 )" - ")" - ")" , output ) ); -} - -void SRDPreprocCmdCoreTest::testTryUnterminated( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -try\n(\n(" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) ); - M_CKERR_( 0 , "unterminated list" , 1 , 1 ); - M_CKERR_( 1 , "unterminated list" , 2 , 1 ); - M_CKERR_( 2 , "unterminated list" , 3 , 1 ); - CPPUNIT_ASSERT( check( "((()))()" , output ) ); -} - -void SRDPreprocCmdCoreTest::testTryTooManyErrors( ) -{ - T_StringBuilder sb; - sb << "(-set (output errors) (-try (\n"; - for ( uint32_t i = 0 ; i < T_SRDErrors::MAX_ERRORS + 1 ; i ++ ) { - sb << "$missing\n"; - } - sb << ") ) )\n" - << "(-set last-error ( ((list)) (-raw\n" - << "(-set (a b) $list)\n" - << "(-if (-eq ($b) ()) ($a) (($last-error $b)))\n" - << ")))\n" - << "(-bless last-error)\n" - << "$output (-length $errors) ($last-error (-unwrap $errors))\n" - << '\0'; - - T_SRDErrors errors; - T_SRDList output( process( sb.data( ) , errors ) ); - - sb.clear( ); - sb << "(()) 41 ( \"too many errors\" ( \"test\" " << ( T_SRDErrors::MAX_ERRORS + 1 ) << " 1 ) )" << '\0'; - CPPUNIT_ASSERT( check( sb.data( ) , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); -} - -void SRDPreprocCmdCoreTest::testTryInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -try -not-a-command )\n" - "( -try $x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(-not-a-command) () ((())) ()" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -namespace { - -class T_OutputErrorGen_ : public A_SRDReaderTarget -{ -private: - A_SRDReaderTarget& next_; - -public: - explicit T_OutputErrorGen_( A_SRDReaderTarget& next ) - : A_SRDReaderTarget( ) , next_( next ) - {} - - void start( T_SRDErrors & errors ) override - { - next_.start( errors ); - } - - void push( T_SRDErrors & errors , T_SRDToken && token ) override - { - if ( token.type( ) == E_SRDTokenType::WORD && token.stringValue( ) == "fail" ) { - errors.add( "DO NOT WANT" , token ); - } - next_.push( errors , std::move( token ) ); - } - - void end( T_SRDErrors & errors ) override - { - next_.end( errors ); - } -}; - -} - -void SRDPreprocCmdCoreTest::testOutput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(5 (-output (3 (-output (1 2)) 4)) 6)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(1 2) (3 4) (5 6)" , output ) ); -} - -void SRDPreprocCmdCoreTest::testOutputErrors( ) -{ - T_SRDErrors errors; - T_SRDMemoryTarget mt( false ); - mt.clearFlushToken( true ); - T_OutputErrorGen_ eg( mt ); - - T_SRDPreprocessorConfig emptyConfig; - emptyConfig.addBuiltinCommands( ); - T_SRDPreprocessor pp( emptyConfig , eg ); - T_SRDLexer lexer( T_String( "test" ) , errors , pp ); - pp.start( errors ); - char const* ptr = "(-try (-output fail))"; - while ( *ptr != 0 ) { - lexer.processCharacter( *ptr ++ ); - } - lexer.processEnd( ); - mt.end( errors ); - - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "fail () ( ( \"DO NOT WANT\" ( \"test\" 1 16 ) ) )" , - mt.list( ) ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testErrorEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "user error" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error fail )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "fail" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error \"out of cheese\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "out of cheese" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "$x" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error 123 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "123" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error 5000000000 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "5000000000" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error 1.5 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "1.5" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error ( a list ( 123 \"wut\" ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "( a list ( 123 wut ) )" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testErrorConcat( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -error And this is the real thing \"(or is it?)\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERR_( 0 , "And this is the real thing (or is it?)" , 1 , 3 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testBreakMain( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "a (-break) b" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "a" , output ) ); -} - -void SRDPreprocCmdCoreTest::testBreakMainList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(a ((-break)) b)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(a())" , output ) ); -} - -void SRDPreprocCmdCoreTest::testBreakEvalInput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "a (-eval (b (-break)) c) d" , errors ) ); - for ( uint32_t i = 0 ; i < errors.size( ) ; i ++ ) { - M_PRINTERR_( i ); - } - CPPUNIT_ASSERT( check( "a (b) d" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); -} - -void SRDPreprocCmdCoreTest::testBreakEvalOutput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "a (-eval b ((-raw ((-break)))) c) d" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "a b (())" , output ) ); -} - -void SRDPreprocCmdCoreTest::testBreakFunction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set f (-raw ( (a b) $a (-break) $b ) ))\n" - "(-bless f)\n" - "a ($f b c) d" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "a b d" , output ) ); -} - -void SRDPreprocCmdCoreTest::testBreakRecursiveFunction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set f (-raw ( (a b)\n" - "(\n" - "(-if (-lt $b $a ) (\n" - "(-break)\n" - "))\n" - "$a\n" - "($f (-add $a 1) $b)\n" - ")\n" - ")))\n" - "(-bless f)\n" - "a ($f 1 3) b" , errors ) ); - for ( auto i = 0u ; i < errors.size( ) ; i ++ ) { - M_PRINTERR_( i ); - } - CPPUNIT_ASSERT( check( "a (1(2(3()))) b" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); -} - -void SRDPreprocCmdCoreTest::testBreakMacro( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( (a b) ($a (-break) $b) ) ))\n" - "a (m b c) d" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "a (b) d" , output ) ); -} - -void SRDPreprocCmdCoreTest::testBreakArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(a (-break even) b)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 5 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "(a)" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -#define M_CKRT_TEXT_( INDEX , TEXT ) \ - CPPUNIT_ASSERT( errors[ INDEX ].error( ) == (TEXT) ) -#define M_CKRT_SOURCE_( INDEX , EID , NAME , LINE , CHAR ) \ - do { \ - RPC_SRDLocation loc( &errors[ INDEX ].location( ) ); \ - int i( EID ); \ - while ( i > 0 ) { \ - assert( loc->isChained( ) ); \ - loc = RPC_SRDLocation( loc->chaining( ).location ); \ - i --; \ - } \ - auto const& l( *loc ); \ - CPPUNIT_ASSERT( l.source( ) == (NAME) ); \ - CPPUNIT_ASSERT( l.line( ) == (LINE) ); \ - CPPUNIT_ASSERT( l.character( ) == (CHAR) ); \ - } while ( 0 ) - -void SRDPreprocCmdCoreTest::testRethrowNothing( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( ( \"error text\"\n" - "( \"source\" 2 3 )\n" - ") ( \"second error\"\n" - "( \"source 2\" 4 5 )\n" - ") ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERRFULL_( 0 , "error text" , false , "source" , 2 , 3 , 0 ); - M_CKERRFULL_( 1 , "second error" , false , "source 2" , 4 , 5 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowEmptyList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowUnwrapped( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error text\"\n" - "( \"source\" 2 3 )\n" - ") ( \"second error\"\n" - "( \"source 2\" 4 5 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERRFULL_( 0 , "error text" , false , "source" , 2 , 3 , 0 ); - M_CKERRFULL_( 1 , "second error" , false , "source 2" , 4 , 5 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowErrorWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow ( error ( \"source\" 2 3 ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERRFULL_( 0 , "error" , false , "source" , 2 , 3 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowSourceWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( source 2 3 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERRFULL_( 0 , "error" , false , "source" , 2 , 3 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowDetails( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"not an error\" details\n" - "( source 2 3 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERRFULL_( 0 , "not an error" , true , "source" , 2 , 3 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChained( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 1 1 )\n" - "called ( \"src\" 2 2 )\n" - "loaded ( \"src\" 3 3 )\n" - "included ( \"src\" 4 4 )\n" - "generated ( \"src\" 5 5 )\n" - "expanded ( \"src\" 6 6 )\n" - "evaluated ( \"src\" 7 7 )\n" - "substituted ( \"src\" 8 8 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERRFULL_( 0 , "error" , false , "src" , 1 , 1 , 7 ); - M_CKERRCHAIN_( 0 , 0 , CALLED , "src" , 2 , 2 , 0 ); - M_CKERRCHAIN_( 0 , 1 , LOADED , "src" , 3 , 3 , 0 ); - M_CKERRCHAIN_( 0 , 2 , INCLUDED , "src" , 4 , 4 , 0 ); - M_CKERRCHAIN_( 0 , 3 , GENERATED , "src" , 5 , 5 , 0 ); - M_CKERRCHAIN_( 0 , 4 , EXPANDED , "src" , 6 , 6 , 0 ); - M_CKERRCHAIN_( 0 , 5 , EVALUATED , "src" , 7 , 7 , 0 ); - M_CKERRCHAIN_( 0 , 6 , SUBSTITUTED , "src" , 8 , 8 , 0 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedDepth( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 1 1 )\n" - "called 5 ( \"src\" 2 2 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - M_CKERRFULL_( 0 , "error" , false , "src" , 1 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 0 , CALLED , "src" , 2 , 2 , 5 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdCoreTest::testRethrowNoList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow nope)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowBadMessage( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow ( 12 ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "error message expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowNoLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow ( error ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "'details' or start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 1 , 19 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowBadLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow ( \"error\" nope ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "'details' or start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 1 , 21 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowLocationBadSource( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-rethrow ( \"error\" ( 12 1 2 ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "source name expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 1 , 23 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowLocationBadLine( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" nope 3 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "line number expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowLocationNegativeLine( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" -1 3 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid line number" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowLocationLineTooHigh( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 5000000000 3 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid line number" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 2 , 9 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowLocationBadChar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 nope )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "character/byte number expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 2 , 11 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowLocationNegativeChar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 -3 )\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid character/byte number" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 2 , 11 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "12\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "chaining type or end of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 3 , 1 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedInvalid( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "blah\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid chaining type" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 3 , 1 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedNoLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "loaded\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "depth or start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 4 , 1 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedBadLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "loaded nope\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "depth or start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 3 , 8 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedNegativeDepth( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "loaded -1\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid recursion depth" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 3 , 8 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedDepthTooHigh( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "loaded 5000000000\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid recursion depth" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 3 , 8 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedDepthNoLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "loaded 5\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 4 , 1 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdCoreTest::testRethrowChainedDepthBadLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-rethrow ( \"error\"\n" - "( \"src\" 2 3 )\n" - "loaded 5 nope\n" - ") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "start of list expected" , 1 , 2 ); - M_CKERR_( 1 , "previous error cause" , 3 , 10 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} diff --git a/tests/srd-preproc-cmd-functions.cc b/tests/srd-preproc-cmd-functions.cc deleted file mode 100644 index b8d32c3..0000000 --- a/tests/srd-preproc-cmd-functions.cc +++ /dev/null @@ -1,441 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - -class SRDPreprocCmdFunctionsTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdFunctionsTest ); - - CPPUNIT_TEST( testBlessNoArgs ); - CPPUNIT_TEST( testBlessMissing ); - CPPUNIT_TEST( testBlessEmpty ); - CPPUNIT_TEST( testBlessInvalid1 ); - CPPUNIT_TEST( testBlessInvalid2 ); - CPPUNIT_TEST( testBlessInvalid3 ); - CPPUNIT_TEST( testBlessInvalid4 ); - CPPUNIT_TEST( testBlessEmptyFunction ); - CPPUNIT_TEST( testBlessFnWithArgs ); - CPPUNIT_TEST( testBlessFnWithDupArgs ); - CPPUNIT_TEST( testBlessFnWithOptArgs ); - CPPUNIT_TEST( testBlessFnWithDupOptArgs ); - CPPUNIT_TEST( testBlessFnWithOptArgsOnly ); - CPPUNIT_TEST( testBlessFnWithDupArgsAll ); - - CPPUNIT_TEST( testCallNoArg ); - CPPUNIT_TEST( testCallBlessedVar ); - CPPUNIT_TEST( testCallBadArg ); - CPPUNIT_TEST( testCallInvalidFunction ); - CPPUNIT_TEST( testCallValidFunction ); - CPPUNIT_TEST( testCallTooManyArgs ); - CPPUNIT_TEST( testCallNotEnoughArgs ); - CPPUNIT_TEST( testCallNotEnoughArgsOpt ); - - CPPUNIT_TEST( testBodyInnerList ); - CPPUNIT_TEST( testDashFunction ); - - CPPUNIT_TEST( testBug00 ); - CPPUNIT_TEST( testBug01 ); - CPPUNIT_TEST( testBug02 ); - CPPUNIT_TEST( testBug03 ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testBlessNoArgs( ); - void testBlessMissing( ); - void testBlessEmpty( ); - void testBlessInvalid1( ); - void testBlessInvalid2( ); - void testBlessInvalid3( ); - void testBlessInvalid4( ); - void testBlessEmptyFunction( ); - void testBlessFnWithArgs( ); - void testBlessFnWithDupArgs( ); - void testBlessFnWithOptArgs( ); - void testBlessFnWithDupOptArgs( ); - void testBlessFnWithOptArgsOnly( ); - void testBlessFnWithDupArgsAll( ); - - void testCallNoArg( ); - void testCallBlessedVar( ); - void testCallBadArg( ); - void testCallInvalidFunction( ); - void testCallValidFunction( ); - void testCallTooManyArgs( ); - void testCallNotEnoughArgs( ); - void testCallNotEnoughArgsOpt( ); - - void testBodyInnerList( ); - void testDashFunction( ); - - void testBug00( ); - void testBug01( ); - void testBug02( ); - void testBug03( ); - -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdFunctionsTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdFunctionsTest::testBlessNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bless )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessMissing( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bless a ) " , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a )\n" - "( -bless a )\n" - "( $a ) " , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 10 ); - CPPUNIT_ASSERT( check( "( )" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessInvalid1( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set x\n" - "nope\n" - ")\n" - "( -bless x )\n" - "($x)" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 4 , 3 ); - M_CKERR_( 1 , "previous error cause" , 4 , 10 ); - CPPUNIT_ASSERT( check( "(nope)" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessInvalid2( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set x\n" - "()\n" - ")\n" - "( -bless x )\n" - "($x)" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 4 , 3 ); - M_CKERR_( 1 , "previous error cause" , 4 , 10 ); - CPPUNIT_ASSERT( check( "(())" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessInvalid3( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set x\n" - "(nope)\n" - ")\n" - "( -bless x )\n" - "($x)" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 4 , 3 ); - M_CKERR_( 1 , "previous error cause" , 4 , 10 ); - CPPUNIT_ASSERT( check( "((nope))" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessInvalid4( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set x\n" - "(()) nope\n" - ")\n" - "( -bless x )\n" - "($x)" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 4 , 3 ); - M_CKERR_( 1 , "previous error cause" , 4 , 10 ); - CPPUNIT_ASSERT( check( "((()) nope)" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessEmptyFunction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( ) x ) )\n" - "( -bless a )\n" - "( $a ) " , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessFnWithArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( u v w ) ( -raw $u $v $w ) ) )\n" - "( -bless a )\n" - "( $a b c d ) " , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "b c d" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessFnWithDupArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( u v u ) ( -raw $u $v ) ) )\n" - "( -bless a )\n" - "( $a b c d ) " , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 10 ); - CPPUNIT_ASSERT( check( "( ( ( u v u ) $u $v ) b c d )" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessFnWithOptArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( u ( v ) ) ( -raw ( $u ) ( $v ) ) ) )\n" - "( -bless a )\n" - "($a b c d)\n" - "($a e)\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( b ) ( c d ) ( e ) ( )" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessFnWithDupOptArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( u ( v v ) ) ( -raw ( $u ) ( $v ) ) ) )\n" - "( -bless a )\n" - "( $a b )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 10 ); - CPPUNIT_ASSERT( check( "( ( ( u ( v v ) ) ( $u ) ( $v ) ) b )" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessFnWithOptArgsOnly( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( ( v ) ) ( -raw ( $v ) ) ) )\n" - "( -bless a )\n" - "( $a ) ( $a b ) ( $a c d )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( ) ( b ) ( c d )" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBlessFnWithDupArgsAll( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set a ( ( u ( v u ) ) ( -raw ( $u ) ( $v ) ) ) )\n" - "( -bless a )\n" - "( $a b )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid function" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 10 ); - CPPUNIT_ASSERT( check( "( ( ( u ( v u ) ) ( $u ) ( $v ) ) b )" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdFunctionsTest::testCallNoArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 9 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallBlessedVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set f (() x))\n" - "(-bless f)\n" - "( -call $f )" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "list expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 9 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallInvalidFunction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call ( nope ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "list expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallValidFunction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call ( -raw ( ( x ( y ) ) $y $x ) ) a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "b c a" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call ( -raw ( ( x ) $x ) ) a b )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 33 ); - CPPUNIT_ASSERT( check( "a" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call ( -raw ( ( x ) $x ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 31 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testCallNotEnoughArgsOpt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -call ( -raw ( ( x y ( z ) ) $x ) ) a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 41 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdFunctionsTest::testBodyInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -call ( -raw ( () -not-a-command ) ) )\n" - "( -call ( -raw ( () $x ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testDashFunction( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set -f ((x) (-raw yo $x)))\n" - "(-bless -f)\n" - "(-f bob)\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "yo bob" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdFunctionsTest::testBug00( ) -{ - /* A bug with tail calls - the code below would output "y x" */ - T_SRDErrors errors; - T_SRDList output( process( - "(-set f1 ((-raw (a) $a)))\n" - "(-set f2 ((-raw (a) ($f1 $a))))\n" - "(-bless f1 f2)\n" - "($f2 x) y\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "x y" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBug01( ) -{ - /* Similar to bug 00, except with an ending parens. */ - T_SRDErrors errors; - T_SRDList output( process( - "(-set f1 ((-raw (a) $a)))\n" - "(-set f2 ((-raw (a) ($f1 $a))))\n" - "(-bless f1 f2)\n" - "(($f2 x))\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(x)" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBug02( ) -{ - /* Causes a crash due to a missing location */ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw (((list))\n" - "(-set (first rest) $list)\n" - "(-if (-length ($first)) (\n" - "($first ($fn $rest))\n" - "))\n" - ")))\n" - "(-bless fn)\n" - "($fn a b)\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(a (b))" , output ) ); -} - -void SRDPreprocCmdFunctionsTest::testBug03( ) -{ - /* More tail-call problems (interaction between the "unswallow" - * part of the evaluator/function feeders and stuff that stands - * between them). - */ - T_SRDErrors errors; - T_SRDList output( process( - "(-set (f1 f2) (-raw\n" - "(() (-if 1 ()))\n" - "(() ($f1))\n" - "))\n" - "(-bless f1 f2)\n" - "(-eval ((-raw -eval) ((-raw $f2))))\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "(a (b))" , output ) ); -} diff --git a/tests/srd-preproc-cmd-input.cc b/tests/srd-preproc-cmd-input.cc deleted file mode 100644 index 91e11bb..0000000 --- a/tests/srd-preproc-cmd-input.cc +++ /dev/null @@ -1,543 +0,0 @@ -#include "srd-preproc-cmd-common.hh" -#include "srd-preproc-location.hh" - - -class SRDPreprocCmdInputTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdInputTest ); - - CPPUNIT_TEST( testFromSourceNoName ); - CPPUNIT_TEST( testFromSourceNamed ); - CPPUNIT_TEST( testFromSourceError ); - CPPUNIT_TEST( testFromSourceErrorNamed ); - CPPUNIT_TEST( testFromSourceTooManyErrors ); - CPPUNIT_TEST( testFromSourceLocation ); - CPPUNIT_TEST( testFromSourceLocationNamed ); - CPPUNIT_TEST( testFromSourceLocationChaining ); - CPPUNIT_TEST( testFromSourceLocationRewind ); - CPPUNIT_TEST( testFromSourceLocationRewindTooMuch ); - - CPPUNIT_TEST( testFromSourceArgsNone ); - CPPUNIT_TEST( testFromSourceArgsExtra ); - CPPUNIT_TEST( testFromSourceArgsBadSource ); - CPPUNIT_TEST( testFromSourceArgsBadName ); - CPPUNIT_TEST( testFromSourceArgsBadChaining ); - CPPUNIT_TEST( testFromSourceArgsBadRewind ); - - CPPUNIT_TEST( testFromSRBNoName ); - CPPUNIT_TEST( testFromSRBNamed ); - CPPUNIT_TEST( testFromSRBError ); - CPPUNIT_TEST( testFromSRBErrorNamed ); - CPPUNIT_TEST( testFromSRBLocation ); - CPPUNIT_TEST( testFromSRBLocationNamed ); - CPPUNIT_TEST( testFromSRBLocationChaining ); - CPPUNIT_TEST( testFromSRBLocationRewind ); - CPPUNIT_TEST( testFromSRBLocationRewindTooMuch ); - - CPPUNIT_TEST( testFromSRBArgsNone ); - CPPUNIT_TEST( testFromSRBArgsExtra ); - CPPUNIT_TEST( testFromSRBArgsBadInput ); - CPPUNIT_TEST( testFromSRBArgsBadName ); - CPPUNIT_TEST( testFromSRBArgsBadChaining ); - CPPUNIT_TEST( testFromSRBArgsBadRewind ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testFromSourceNoName( ); - void testFromSourceNamed( ); - void testFromSourceError( ); - void testFromSourceErrorNamed( ); - void testFromSourceTooManyErrors( ); - void testFromSourceLocation( ); - void testFromSourceLocationNamed( ); - void testFromSourceLocationChaining( ); - void testFromSourceLocationRewind( ); - void testFromSourceLocationRewindTooMuch( ); - - void testFromSourceArgsNone( ); - void testFromSourceArgsExtra( ); - void testFromSourceArgsBadSource( ); - void testFromSourceArgsBadName( ); - void testFromSourceArgsBadChaining( ); - void testFromSourceArgsBadRewind( ); - - void testFromSRBNoName( ); - void testFromSRBNamed( ); - void testFromSRBError( ); - void testFromSRBErrorNamed( ); - void testFromSRBLocation( ); - void testFromSRBLocationNamed( ); - void testFromSRBLocationChaining( ); - void testFromSRBLocationRewind( ); - void testFromSRBLocationRewindTooMuch( ); - - void testFromSRBArgsNone( ); - void testFromSRBArgsExtra( ); - void testFromSRBArgsBadInput( ); - void testFromSRBArgsBadName( ); - void testFromSRBArgsBadChaining( ); - void testFromSRBArgsBadRewind( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdInputTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdInputTest::testFromSourceNoName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source \"word \\\"string\\\" 123 5000000000 1.2 $x ( some list )\" )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "word \"string\" 123 5000000000 1.2 $x ( some list )" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceNamed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-source \"word \\\"string\\\" 123 5000000000 1.2 $x ( some list )\"\n" - "\"some_random_file.srd\" )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "word \"string\" 123 5000000000 1.2 $x ( some list )" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source\n\"( a\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unterminated list" , 1 , 1 ); - CPPUNIT_ASSERT( errors[ 0 ].location( ).source( ) == "-from-source" ); - CPPUNIT_ASSERT( check( "( a )" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceErrorNamed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source\n\"( a\" \"some_random_file.srd\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unterminated list" , 1 , 1 ); - CPPUNIT_ASSERT( errors[ 0 ].location( ).source( ) == "some_random_file.srd" ); - CPPUNIT_ASSERT( check( "( a )" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceTooManyErrors( ) -{ - T_StringBuilder sb( "( -from-source \"" ); - for ( auto i = 0u ; i < T_SRDErrors::MAX_ERRORS + 1 ; i ++ ) { - sb << "(\\u00a1"; - } - sb << "\" )" << '\0'; - - try { - T_SRDErrors errors; - T_SRDList output( process( sb.data( ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( T_SRDErrors::MAX_ERRORS + 1 ) , errors.size( ) ); - for ( auto i = 0u ; i < T_SRDErrors::MAX_ERRORS ; i ++ ) { - M_CKERR_( i , "unexpected character" , 1 , ( i + 1 ) * 2 ); - } - M_CKERR_( T_SRDErrors::MAX_ERRORS , "too many errors" , 1 , 80 ); - - sb.clear( ); - for ( auto i = 0u ; i < T_SRDErrors::MAX_ERRORS ; i ++ ) { - sb << '('; - } - for ( auto i = 0u ; i < T_SRDErrors::MAX_ERRORS ; i ++ ) { - sb << ')'; - } - sb << '\0'; - CPPUNIT_ASSERT( check( sb.data( ) , output ) ); - } catch ( X_SRDErrors const& e ) { - auto const& errors( e.errors ); - for ( auto i = 0u ; i < errors.size( ) ; i ++ ) { - M_PRINTERR_( i ); - } - CPPUNIT_FAIL( "Shouldn't fail with exception" ); - } -} - -void SRDPreprocCmdInputTest::testFromSourceLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source \"test\\ntest\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "test test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "-from-source" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "-from-source" , 2 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSourceLocationNamed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source \"test\\ntest\" \"test.srd\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "test test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test.srd" , 2 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSourceLocationChaining( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source \"test\\ntest\" \"test.srd\" loaded )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "test test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , LOADED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test.srd" , 2 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , LOADED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSourceLocationRewind( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set doit ((-raw ()\n" - "( -from-source \"test\" \"test.srd\" loaded 2 )\n" - ")))\n" - "(-set tfn ((-raw (x)\n" - "(-if (-lt $x 1) (\n" - "($doit)\n" - ")(\n" - "($tfn (-sub $x 1))\n" - "))\n" - ")))\n" - "(-bless tfn doit)\n" - "($tfn 5)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , LOADED , "test" , 12 , 2 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSourceLocationRewindTooMuch( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source \"test\" \"test.srd\" loaded 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , LOADED , "test" , 1 , 3 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdInputTest::testFromSourceArgsNone( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceArgsExtra( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source \"x\" \"y\" generated 0 c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 36 ); - CPPUNIT_ASSERT( check( "x" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceArgsBadSource( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-source 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSourceArgsBadName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-source \"test\"\n" - "12 )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - CPPUNIT_ASSERT( check( "test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "-from-source" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSourceArgsBadChaining( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-source \"test\" \"test.srd\"\n" - "nope )\n" - "( -from-source \"test\" \"test2.srd\"\n" - "12 )\n" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "'generated', 'included' or 'loaded' expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - M_CKERR_( 2 , "'generated', 'included' or 'loaded' expected" , 3 , 3 ); - M_CKERR_( 3 , "previous error cause" , 4 , 1 ); - CPPUNIT_ASSERT( check( "test test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test2.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 3 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSourceArgsBadRewind( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-source \"test\" \"test.srd\" generated\n" - "-1 )\n" - "( -from-source \"test\" \"test2.srd\" generated\n" - "nope )\n" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - M_CKERR_( 2 , "integer argument expected" , 3 , 3 ); - M_CKERR_( 3 , "previous error cause" , 4 , 1 ); - CPPUNIT_ASSERT( check( "test test" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test2.srd" , 1 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 3 , 3 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -#define SRB_PROLOGUE_ \ - "ce a1 7c ea " \ - "00 ee ff c0" - -#define SRB_DATA_ \ - "[ " \ - SRB_PROLOGUE_ \ - "02 03 00 00 00 4c 4f 4c" \ - "00" \ - "]" - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdInputTest::testFromSRBNoName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb " SRB_DATA_ " )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBNamed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-srb " SRB_DATA_ "\n" - "\"some_random_file.srb\" )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBError( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb\n[ " SRB_PROLOGUE_ " ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unexpected end of file" , 0 , 8 ); - CPPUNIT_ASSERT( errors[ 0 ].location( ).source( ) == "-from-srb" ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBErrorNamed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-srb\n[ " - SRB_PROLOGUE_ - " ] \"some_random_file.srb\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unexpected end of file" , 0 , 8 ); - CPPUNIT_ASSERT( errors[ 0 ].location( ).source( ) == "some_random_file.srb" ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBLocation( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb " SRB_DATA_ " )\n" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "-from-srb" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSRBLocationNamed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb " SRB_DATA_ " \"test.srb\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srb" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSRBLocationChaining( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb " SRB_DATA_ " \"test.srb\" loaded )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srb" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , LOADED , "test" , 1 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSRBLocationRewind( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set doit ((-raw ()\n" - "( -from-srb " SRB_DATA_ " \"test.srb\" loaded 2 )\n" - ")))\n" - "(-set tfn ((-raw (x)\n" - "(-if (-lt $x 1) (\n" - "($doit)\n" - ")(\n" - "($tfn (-sub $x 1))\n" - "))\n" - ")))\n" - "(-bless tfn doit)\n" - "($tfn 5)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srb" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , LOADED , "test" , 12 , 2 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSRBLocationRewindTooMuch( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb " SRB_DATA_ " \"test.srb\" loaded 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srb" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , LOADED , "test" , 1 , 3 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdInputTest::testFromSRBArgsNone( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBArgsExtra( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb " SRB_DATA_ " a loaded 0\nnope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBArgsBadInput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -from-srb \"x\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "binary array argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBArgsBadName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-srb " SRB_DATA_ "\n12 )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - CPPUNIT_ASSERT( check( "LOL" , output ) ); -} - -void SRDPreprocCmdInputTest::testFromSRBArgsBadChaining( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-srb " SRB_DATA_ " \"test.srb\"\n" - "nope )\n" - "( -from-srb " SRB_DATA_ " \"test2.srb\"\n" - "12 )\n" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "'generated', 'included' or 'loaded' expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - M_CKERR_( 2 , "'generated', 'included' or 'loaded' expected" , 3 , 3 ); - M_CKERR_( 3 , "previous error cause" , 4 , 1 ); - CPPUNIT_ASSERT( check( "LOL LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srb" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test2.srb" , 0 , 8 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 3 , 3 , 0 ); -} - -void SRDPreprocCmdInputTest::testFromSRBArgsBadRewind( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -from-srb " SRB_DATA_ " \"test.srd\" generated\n" - "-1 )\n" - "( -from-srb " SRB_DATA_ " \"test2.srd\" generated\n" - "nope )\n" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - M_CKERR_( 2 , "integer argument expected" , 3 , 3 ); - M_CKERR_( 3 , "previous error cause" , 4 , 1 ); - CPPUNIT_ASSERT( check( "LOL LOL" , output ) ); - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test.srd" , 0 , 8 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 3 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test2.srd" , 0 , 8 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 3 , 3 , 0 ); -} diff --git a/tests/srd-preproc-cmd-introspect.cc b/tests/srd-preproc-cmd-introspect.cc deleted file mode 100644 index e51d727..0000000 --- a/tests/srd-preproc-cmd-introspect.cc +++ /dev/null @@ -1,322 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdIntrospectTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdIntrospectTest ); - - CPPUNIT_TEST( testIsSetMissingArgs ); - CPPUNIT_TEST( testIsSetExtraArgs ); - CPPUNIT_TEST( testIsSetBadArg ); - CPPUNIT_TEST( testIsSetTrue ); - CPPUNIT_TEST( testIsSetFalse ); - - CPPUNIT_TEST( testIsMacroMissingArgs ); - CPPUNIT_TEST( testIsMacroExtraArgs ); - CPPUNIT_TEST( testIsMacroBadArg ); - CPPUNIT_TEST( testIsMacroTrue ); - CPPUNIT_TEST( testIsMacroFalse ); - - CPPUNIT_TEST( testIsBlessedMissingArgs ); - CPPUNIT_TEST( testIsBlessedExtraArgs ); - CPPUNIT_TEST( testIsBlessedBadArg ); - CPPUNIT_TEST( testIsBlessedUnset ); - CPPUNIT_TEST( testIsBlessedUnblessed ); - CPPUNIT_TEST( testIsBlessedTrue ); - - CPPUNIT_TEST( testTypeOfMissingArg ); - CPPUNIT_TEST( testTypeOfExtraArgs ); - CPPUNIT_TEST( testTypeOfList ); - CPPUNIT_TEST( testTypeOfWord ); - CPPUNIT_TEST( testTypeOfString ); - CPPUNIT_TEST( testTypeOfInt ); - CPPUNIT_TEST( testTypeOfLong ); - CPPUNIT_TEST( testTypeOfReal ); - CPPUNIT_TEST( testTypeOfVar ); - CPPUNIT_TEST( testTypeOfBinary ); - CPPUNIT_TEST( testTypeOfComment ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testIsSetMissingArgs( ); - void testIsSetExtraArgs( ); - void testIsSetBadArg( ); - void testIsSetTrue( ); - void testIsSetFalse( ); - - void testIsMacroMissingArgs( ); - void testIsMacroExtraArgs( ); - void testIsMacroBadArg( ); - void testIsMacroTrue( ); - void testIsMacroFalse( ); - - void testIsBlessedMissingArgs( ); - void testIsBlessedExtraArgs( ); - void testIsBlessedBadArg( ); - void testIsBlessedUnset( ); - void testIsBlessedUnblessed( ); - void testIsBlessedTrue( ); - - void testTypeOfMissingArg( ); - void testTypeOfExtraArgs( ); - void testTypeOfList( ); - void testTypeOfWord( ); - void testTypeOfString( ); - void testTypeOfInt( ); - void testTypeOfLong( ); - void testTypeOfReal( ); - void testTypeOfVar( ); - void testTypeOfBinary( ); - void testTypeOfComment( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdIntrospectTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdIntrospectTest::testIsSetMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-set )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsSetExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-set a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsSetBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-set 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "word expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsSetTrue( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set x 1)( -is-set x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsSetFalse( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-set x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdIntrospectTest::testIsMacroMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-macro )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsMacroExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-macro a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsMacroBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-macro 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "word expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsMacroTrue( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set-macro x (()))( -is-macro x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsMacroFalse( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-macro x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdIntrospectTest::testIsBlessedMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-blessed )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsBlessedExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-blessed a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 17 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsBlessedBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-blessed 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "word expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 15 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsBlessedUnset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -is-blessed x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsBlessedUnblessed( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set x 1)( -is-blessed x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testIsBlessedTrue( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set x (()) )\n" - "( -bless x )\n" - "( -is-blessed x )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdIntrospectTest::testTypeOfMissingArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "none" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "word" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "list" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of w )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "word" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of \"w\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "string" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "int" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of 12123456789 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "long" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfReal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of 0. )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "real" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of ( -raw $x ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "var" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of [] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "binary" , output ) ); -} - -void SRDPreprocCmdIntrospectTest::testTypeOfComment( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -type-of (-from-source \"{x}\") )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "comment" , output ) ); -} diff --git a/tests/srd-preproc-cmd-logic.cc b/tests/srd-preproc-cmd-logic.cc deleted file mode 100644 index 52374a3..0000000 --- a/tests/srd-preproc-cmd-logic.cc +++ /dev/null @@ -1,609 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdLogicTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdLogicTest ); - - CPPUNIT_TEST( testNotNoArgs ); - CPPUNIT_TEST( testNotTooManyArgs ); - CPPUNIT_TEST( testNotBadArg ); - CPPUNIT_TEST( testNotZero ); - CPPUNIT_TEST( testNotNonZeroInt ); - CPPUNIT_TEST( testNotNonZeroLong ); - - CPPUNIT_TEST( testBwNotNoArgs ); - CPPUNIT_TEST( testBwNotTooManyArgs ); - CPPUNIT_TEST( testBwNotBadArg ); - CPPUNIT_TEST( testBwNotInt ); - CPPUNIT_TEST( testBwNotLong ); - - CPPUNIT_TEST( testAndNoArgs ); - CPPUNIT_TEST( testAndBadArgs ); - CPPUNIT_TEST( testAnd00 ); - CPPUNIT_TEST( testAnd01 ); - CPPUNIT_TEST( testAnd10 ); - CPPUNIT_TEST( testAnd11 ); - CPPUNIT_TEST( testAndMultiple ); - CPPUNIT_TEST( testAndLong ); - CPPUNIT_TEST( testAndSillyValues ); - - CPPUNIT_TEST( testBwAndNoArgs ); - CPPUNIT_TEST( testBwAndBadArgs ); - CPPUNIT_TEST( testBwAndInts ); - CPPUNIT_TEST( testBwAndLongs ); - CPPUNIT_TEST( testBwAndMultiple ); - - CPPUNIT_TEST( testOrNoArgs ); - CPPUNIT_TEST( testOrBadArgs ); - CPPUNIT_TEST( testOr00 ); - CPPUNIT_TEST( testOr01 ); - CPPUNIT_TEST( testOr10 ); - CPPUNIT_TEST( testOr11 ); - CPPUNIT_TEST( testOrMultiple ); - CPPUNIT_TEST( testOrLong ); - CPPUNIT_TEST( testOrSillyValues ); - - CPPUNIT_TEST( testBwOrNoArgs ); - CPPUNIT_TEST( testBwOrBadArgs ); - CPPUNIT_TEST( testBwOrInts ); - CPPUNIT_TEST( testBwOrLongs ); - CPPUNIT_TEST( testBwOrMultiple ); - - CPPUNIT_TEST( testXorNoArgs ); - CPPUNIT_TEST( testXorBadArgs ); - CPPUNIT_TEST( testXor00 ); - CPPUNIT_TEST( testXor01 ); - CPPUNIT_TEST( testXor10 ); - CPPUNIT_TEST( testXor11 ); - CPPUNIT_TEST( testXorMultiple ); - CPPUNIT_TEST( testXorLong ); - CPPUNIT_TEST( testXorSillyValues ); - - CPPUNIT_TEST( testBwXorNoArgs ); - CPPUNIT_TEST( testBwXorBadArgs ); - CPPUNIT_TEST( testBwXorInts ); - CPPUNIT_TEST( testBwXorLongs ); - CPPUNIT_TEST( testBwXorMultiple ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testNotNoArgs( ); - void testNotTooManyArgs( ); - void testNotBadArg( ); - void testNotZero( ); - void testNotNonZeroInt( ); - void testNotNonZeroLong( ); - - void testBwNotNoArgs( ); - void testBwNotTooManyArgs( ); - void testBwNotBadArg( ); - void testBwNotInt( ); - void testBwNotLong( ); - - void testAndNoArgs( ); - void testAndBadArgs( ); - void testAnd00( ); - void testAnd01( ); - void testAnd10( ); - void testAnd11( ); - void testAndMultiple( ); - void testAndLong( ); - void testAndSillyValues( ); - - void testBwAndNoArgs( ); - void testBwAndBadArgs( ); - void testBwAndInts( ); - void testBwAndLongs( ); - void testBwAndMultiple( ); - - void testOrNoArgs( ); - void testOrBadArgs( ); - void testOr00( ); - void testOr01( ); - void testOr10( ); - void testOr11( ); - void testOrMultiple( ); - void testOrLong( ); - void testOrSillyValues( ); - - void testBwOrNoArgs( ); - void testBwOrBadArgs( ); - void testBwOrInts( ); - void testBwOrLongs( ); - void testBwOrMultiple( ); - - void testXorNoArgs( ); - void testXorBadArgs( ); - void testXor00( ); - void testXor01( ); - void testXor10( ); - void testXor11( ); - void testXorMultiple( ); - void testXorLong( ); - void testXorSillyValues( ); - - void testBwXorNoArgs( ); - void testBwXorBadArgs( ); - void testBwXorInts( ); - void testBwXorLongs( ); - void testBwXorMultiple( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdLogicTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testNotNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -not )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testNotTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -not 0 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testNotBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -not 0. )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testNotZero( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -not 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testNotNonZeroInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -not 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testNotNonZeroLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set x ( -not 12000000000 ))(-to-integer $x)(-type-of $x)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0 long" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testBwNotNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-not )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwNotTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-not 1 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "-2" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwNotBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-not 2.2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "-3" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwNotInt( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-not 129 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-130" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwNotLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-not 12000000000 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-12000000001" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testAndNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAndBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 1 1. ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAnd00( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 0 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAnd01( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 0 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAnd10( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 1 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAnd11( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 1 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAndMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 1 1 1 1 )( -and 1 0 1 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAndLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and 1 ( -to-long 1 ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testAndSillyValues( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -and -42384 35845 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testBwAndNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-and )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwAndBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-and 1.2 ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwAndInts( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-and 5 6 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "4" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwAndLongs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-and 12884901888 4294967296 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "4294967296" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwAndMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-and 15 7 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "3" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testOrNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 7 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOrBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 1 1. ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 9 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOr00( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 0 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOr01( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 0 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOr10( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 1 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOr11( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 1 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOrMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 1 1 1 1 )( -or 1 0 1 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOrLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 1 ( -to-long 1 ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testOrSillyValues( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -or 0 35845 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testBwOrNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-or )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwOrBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-or 1.2 ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwOrInts( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-or 5 6 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "7" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwOrLongs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-or 8589934592 4294967296 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "12884901888" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwOrMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-or 2 4 8 6 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "14" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testXorNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXorBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 1 1. ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXor00( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 0 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXor01( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 0 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXor10( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 1 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXor11( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 1 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXorMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 1 0 0 0 )( -xor 1 0 1 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXorLong( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 1 ( -to-long 1 ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testXorSillyValues( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -xor 0 35845 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdLogicTest::testBwXorNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-xor )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwXorBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-xor 1.2 ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwXorInts( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-xor 5 6 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "3" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwXorLongs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-xor 21474836480 25769803776 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "12884901888" , output ) ); -} - -void SRDPreprocCmdLogicTest::testBwXorMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -bw-xor 2 4 8 6 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "8" , output ) ); -} diff --git a/tests/srd-preproc-cmd-macros.cc b/tests/srd-preproc-cmd-macros.cc deleted file mode 100644 index 1f0105e..0000000 --- a/tests/srd-preproc-cmd-macros.cc +++ /dev/null @@ -1,243 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdMacrosTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdMacrosTest ); - - CPPUNIT_TEST( testSetMacroEmpty ); - CPPUNIT_TEST( testSetMacroMissingArgs ); - CPPUNIT_TEST( testSetMacroExtraArgs ); - CPPUNIT_TEST( testSetMacroBadName ); - CPPUNIT_TEST( testSetMacroBadBody ); - CPPUNIT_TEST( testSetMacroInvalidBody ); - CPPUNIT_TEST( testSetMacroSuccess ); - CPPUNIT_TEST( testSetMacroDuplicate ); - - CPPUNIT_TEST( testUnsetMacroNoArgs ); - CPPUNIT_TEST( testUnsetMacro ); - CPPUNIT_TEST( testUnsetMacroMissing ); - CPPUNIT_TEST( testUnsetMacroMultiple ); - - CPPUNIT_TEST( testListMacros ); - CPPUNIT_TEST( testListMacrosArgs ); - - CPPUNIT_TEST( testMacroBodyInnerList ); - CPPUNIT_TEST( testMacroOutputInnerList ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testSetMacroEmpty( ); - void testSetMacroMissingArgs( ); - void testSetMacroExtraArgs( ); - void testSetMacroBadName( ); - void testSetMacroBadBody( ); - void testSetMacroInvalidBody( ); - void testSetMacroSuccess( ); - void testSetMacroDuplicate( ); - - void testUnsetMacroNoArgs( ); - void testUnsetMacro( ); - void testUnsetMacroMissing( ); - void testUnsetMacroMultiple( ); - - void testListMacros( ); - void testListMacrosArgs( ); - - void testMacroBodyInnerList( ); - void testMacroOutputInnerList( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdMacrosTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMacrosTest::testSetMacroEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set-macro )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroMissingArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set-macro a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid macro" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set-macro a ( () ) x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 23 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroBadName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set-macro 1 ( () ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "word expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroBadBody( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set-macro a x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid macro" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroInvalidBody( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set-macro a ( nope ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid macro" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroSuccess( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro test ( -raw ( ((list)) ( (-raw -raw) $list ) ) ) )\n" - "(test $x $y $z (-set x 1))", - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "$x $y $z (-set x 1)" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testSetMacroDuplicate( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro a (()) )\n" - "( -set-macro a (()) )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "duplicate macro" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 14 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMacrosTest::testUnsetMacroNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unset-macro ) " , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testUnsetMacro( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro a (()1) )\n" - "(a)\n" - "( -unset-macro a )\n" - "(a)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "1 (a)" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testUnsetMacroMissing( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unset-macro a )(a)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "(a)" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testUnsetMacroMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro a (()1) )\n" - "( -set-macro b (()2) )\n" - "( -set-macro c (()3) )\n" - "( -unset-macro a c d )\n" - "(a)(b)(c)\n" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "(a) 2 (c)" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMacrosTest::testListMacros( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x )\n" - "( -set-macro y ( ( ) ) )\n" - "( -set f (-raw (() ((-ls-macros))) ))\n" - "( -bless f )\n" - "( ( -ls-macros ) )\n" - "( -scope\n" - "( -unset-macro y )\n" - "( ( -ls-macros ) )\n" - ")\n" - "($f)\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( y ) ( ) ( y )" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testListMacrosArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro y ( ( ) ) )\n" - "( -ls-macros blah )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 14 ); - CPPUNIT_ASSERT( check( "y" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMacrosTest::testMacroBodyInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro x (-raw ( () -not-a-command ) ) )\n" - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -set-macro y (-raw ( () $x ) ) )\n" - "(x)(y)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); -} - -void SRDPreprocCmdMacrosTest::testMacroOutputInnerList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set-macro x (-raw ( () (-raw -not-a-command) ) ) )\n" - "( -set x (-raw ( () ) ) )\n" - "( -bless x )\n" - "( -set-macro y (-raw ( () (-raw $x ) ) ) )\n" - "(x)(y)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-not-a-command (())" , output ) ); -} diff --git a/tests/srd-preproc-cmd-misc.cc b/tests/srd-preproc-cmd-misc.cc deleted file mode 100644 index 335578a..0000000 --- a/tests/srd-preproc-cmd-misc.cc +++ /dev/null @@ -1,165 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdMiscTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdMiscTest ); - - CPPUNIT_TEST( testIgnore ); - - CPPUNIT_TEST( testUnwrapMissingArg ); - CPPUNIT_TEST( testUnwrapBadArg ); - CPPUNIT_TEST( testUnwrapEmptyList ); - CPPUNIT_TEST( testUnwrapList ); - CPPUNIT_TEST( testUnwrapExtraArgs ); - - CPPUNIT_TEST( testLengthMissingArg ); - CPPUNIT_TEST( testLengthExtraArgs ); - CPPUNIT_TEST( testLengthBadArg ); - CPPUNIT_TEST( testLengthList ); - CPPUNIT_TEST( testLengthWord ); - CPPUNIT_TEST( testLengthString ); - CPPUNIT_TEST( testLengthBinary ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testIgnore( ); - - void testUnwrapMissingArg( ); - void testUnwrapBadArg( ); - void testUnwrapEmptyList( ); - void testUnwrapList( ); - void testUnwrapExtraArgs( ); - - void testLengthMissingArg( ); - void testLengthExtraArgs( ); - void testLengthBadArg( ); - void testLengthList( ); - void testLengthWord( ); - void testLengthString( ); - void testLengthBinary( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdMiscTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMiscTest::testIgnore( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ignore $does-not-exist ( -fail ) bleh )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMiscTest::testUnwrapMissingArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unwrap )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMiscTest::testUnwrapBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unwrap a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "list expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMiscTest::testUnwrapEmptyList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unwrap ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdMiscTest::testUnwrapList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unwrap ( a b c ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "a b c" , output ) ); -} - -void SRDPreprocCmdMiscTest::testUnwrapExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unwrap ( a ) ( b c ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 17 ); - CPPUNIT_ASSERT( check( "a" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdMiscTest::testLengthMissingArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "-1" , output ) ); -} - -void SRDPreprocCmdMiscTest::testLengthExtraArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 13 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdMiscTest::testLengthBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "list, word, string or binary array expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "-1" , output ) ); -} - -void SRDPreprocCmdMiscTest::testLengthList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length ( a ( b ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "2" , output ) ); -} - -void SRDPreprocCmdMiscTest::testLengthWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length abc )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "3" , output ) ); -} - -void SRDPreprocCmdMiscTest::testLengthString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length \"some string\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "11" , output ) ); -} - -void SRDPreprocCmdMiscTest::testLengthBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -length [ 01 02 03 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "3" , output ) ); -} diff --git a/tests/srd-preproc-cmd-strings.cc b/tests/srd-preproc-cmd-strings.cc deleted file mode 100644 index 8927566..0000000 --- a/tests/srd-preproc-cmd-strings.cc +++ /dev/null @@ -1,931 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdStringsTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdStringsTest ); - - CPPUNIT_TEST( testConcatNoArgs ); - CPPUNIT_TEST( testConcatBadArgs ); - CPPUNIT_TEST( testConcatOneString ); - CPPUNIT_TEST( testConcatStrings ); - CPPUNIT_TEST( testConcatStringWord ); - CPPUNIT_TEST( testConcatStringNumeric ); - CPPUNIT_TEST( testConcatStringBinary ); - CPPUNIT_TEST( testConcatOneBinary ); - CPPUNIT_TEST( testConcatBinary ); - - CPPUNIT_TEST( testSubstrNotEnoughArgs ); - CPPUNIT_TEST( testSubstrStringNotEnoughArgs ); - CPPUNIT_TEST( testSubstrBinaryNotEnoughArgs ); - CPPUNIT_TEST( testSubstrStringTooManyArgs ); - CPPUNIT_TEST( testSubstrBinaryTooManyArgs ); - CPPUNIT_TEST( testSubstrBadTooManyArgs ); - CPPUNIT_TEST( testSubstrStringOffset ); - CPPUNIT_TEST( testSubstrBinaryOffset ); - CPPUNIT_TEST( testSubstrBadOffset ); - CPPUNIT_TEST( testSubstrStringBad ); - CPPUNIT_TEST( testSubstrStringInvalid ); - CPPUNIT_TEST( testSubstrStringHigh ); - CPPUNIT_TEST( testSubstrStringOffsetLength ); - CPPUNIT_TEST( testSubstrBinaryOffsetLength ); - CPPUNIT_TEST( testSubstrStringOffsetBad ); - CPPUNIT_TEST( testSubstrStringOffsetToOffset ); - CPPUNIT_TEST( testSubstrBinaryOffsetToOffset ); - CPPUNIT_TEST( testSubstrStringRangeInverted ); - CPPUNIT_TEST( testSubstrBinaryRangeInverted ); - CPPUNIT_TEST( testSubstrStringOffsetBadOffset ); - CPPUNIT_TEST( testSubstrStringOffsetToBad ); - CPPUNIT_TEST( testSubstrRangeInvalidStart ); - CPPUNIT_TEST( testSubstrRangeInvalidEnd ); - - CPPUNIT_TEST( testSplitNotEnoughArgs ); - CPPUNIT_TEST( testSplitTooManyArgs ); - CPPUNIT_TEST( testSplitBadString ); - CPPUNIT_TEST( testSplitStringBad ); - CPPUNIT_TEST( testSplitStringEmpty ); - CPPUNIT_TEST( testSplitStringStringBad ); - CPPUNIT_TEST( testSplitStringStringNegative ); - CPPUNIT_TEST( testSplitSingleNormal ); - CPPUNIT_TEST( testSplitSingleStart ); - CPPUNIT_TEST( testSplitSingleEnd ); - CPPUNIT_TEST( testSplitSingleNowhere ); - CPPUNIT_TEST( testSplitMultiNormal ); - CPPUNIT_TEST( testSplitMultiStart ); - CPPUNIT_TEST( testSplitMultiEnd ); - CPPUNIT_TEST( testSplitMultiNowhere ); - CPPUNIT_TEST( testSplitMultiLonger ); - CPPUNIT_TEST( testSplitLimitZero ); - CPPUNIT_TEST( testSplitLimit ); - CPPUNIT_TEST( testSplitLimitGreater ); - - CPPUNIT_TEST( testSWNotEnoughArgs ); - CPPUNIT_TEST( testSWTooManyArgs ); - CPPUNIT_TEST( testSWStringYes ); - CPPUNIT_TEST( testSWStringYesEqual ); - CPPUNIT_TEST( testSWStringYesEmpty ); - CPPUNIT_TEST( testSWStringNoShorter ); - CPPUNIT_TEST( testSWStringNoLonger ); - CPPUNIT_TEST( testSWBinaryYes ); - CPPUNIT_TEST( testSWBinaryYesEqual ); - CPPUNIT_TEST( testSWBinaryYesEmpty ); - CPPUNIT_TEST( testSWBinaryNoShorter ); - CPPUNIT_TEST( testSWBinaryNoLonger ); - CPPUNIT_TEST( testSWWordString ); - CPPUNIT_TEST( testSWStringWord ); - CPPUNIT_TEST( testSWStringBad ); - CPPUNIT_TEST( testSWBadString ); - - CPPUNIT_TEST( testEWNotEnoughArgs ); - CPPUNIT_TEST( testEWTooManyArgs ); - CPPUNIT_TEST( testEWStringYes ); - CPPUNIT_TEST( testEWStringYesEqual ); - CPPUNIT_TEST( testEWStringYesEmpty ); - CPPUNIT_TEST( testEWStringNoShorter ); - CPPUNIT_TEST( testEWStringNoLonger ); - CPPUNIT_TEST( testEWBinaryYes ); - CPPUNIT_TEST( testEWBinaryYesEqual ); - CPPUNIT_TEST( testEWBinaryYesEmpty ); - CPPUNIT_TEST( testEWBinaryNoShorter ); - CPPUNIT_TEST( testEWBinaryNoLonger ); - CPPUNIT_TEST( testEWWordString ); - CPPUNIT_TEST( testEWStringWord ); - CPPUNIT_TEST( testEWStringBad ); - CPPUNIT_TEST( testEWBadString ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - // -concat - void testConcatNoArgs( ); - void testConcatBadArgs( ); - void testConcatOneString( ); - void testConcatStrings( ); - void testConcatStringWord( ); - void testConcatStringNumeric( ); - void testConcatStringBinary( ); - void testConcatOneBinary( ); - void testConcatBinary( ); - - // -substr - void testSubstrNotEnoughArgs( ); // Not enough arguments - void testSubstrStringNotEnoughArgs( ); // String - void testSubstrBinaryNotEnoughArgs( ); // Binary - void testSubstrStringTooManyArgs( ); // String + too many arguments - void testSubstrBinaryTooManyArgs( ); // Binary + too many arguments - void testSubstrBadTooManyArgs( ); // Invalid argument + too many arguments - void testSubstrStringOffset( ); // String and offset arguments - void testSubstrBinaryOffset( ); // Binary data and offset arguments - void testSubstrBadOffset( ); // Invalid argument + offset - void testSubstrStringBad( ); // String + invalid argument - void testSubstrStringInvalid( ); // String, offset < 0 - void testSubstrStringHigh( ); // String, offset > length - void testSubstrStringOffsetLength( ); // String, offset and length arguments - void testSubstrBinaryOffsetLength( ); // Binary, offset and length arguments - void testSubstrStringOffsetBad( ); // String and offset followed by invalid argument - void testSubstrStringOffsetToOffset( ); // String, range mode - void testSubstrBinaryOffsetToOffset( ); // Binary, range mode - void testSubstrStringRangeInverted( ); // String, range mode, end < start - void testSubstrBinaryRangeInverted( ); // Binary, range mode, end < start - void testSubstrStringOffsetBadOffset( ); - // String, range mode, wrong "to" argument - void testSubstrStringOffsetToBad( ); // String, range mode, wrong end argument - void testSubstrRangeInvalidStart( ); // String, range mode, start < 0 - void testSubstrRangeInvalidEnd( ); // String, range mode, end < 0 - - // -str-split - void testSplitNotEnoughArgs( ); // Not enough arguments - void testSplitTooManyArgs( ); // Too many arguments - void testSplitBadString( ); // Invalid argument, string - void testSplitStringBad( ); // String, invalid argument - void testSplitStringEmpty( ); // String, empty string - void testSplitStringStringBad( ); // String, string, invalid argument - void testSplitStringStringNegative( ); // String, string, negative integer - void testSplitSingleNormal( ); // Single-character delimiter, inside string - void testSplitSingleStart( ); // Single-character delimiter, start of string - void testSplitSingleEnd( ); // Single-character delimiter, end of string - void testSplitSingleNowhere( ); // Single-character delimiter, not in string - void testSplitMultiNormal( ); // Multi-character delimiter, inside string - void testSplitMultiStart( ); // Multi-character delimiter, start of string - void testSplitMultiEnd( ); // Multi-character delimiter, end of string - void testSplitMultiNowhere( ); // Multi-character delimiter, not in string - void testSplitMultiLonger( ); // Multi-character delimiter, longer than string - void testSplitLimitZero( ); // With limit set to 0 - void testSplitLimit( ); // With a non-zero limit - void testSplitLimitGreater( ); // With a limit higher than the result count - - // -starts-with - void testSWNotEnoughArgs( ); - void testSWTooManyArgs( ); - void testSWStringYes( ); - void testSWStringYesEqual( ); - void testSWStringYesEmpty( ); - void testSWStringNoShorter( ); - void testSWStringNoLonger( ); - void testSWBinaryYes( ); - void testSWBinaryYesEqual( ); - void testSWBinaryYesEmpty( ); - void testSWBinaryNoShorter( ); - void testSWBinaryNoLonger( ); - void testSWWordString( ); - void testSWStringWord( ); - void testSWStringBad( ); - void testSWBadString( ); - - // -ends-with - void testEWNotEnoughArgs( ); - void testEWTooManyArgs( ); - void testEWStringYes( ); - void testEWStringYesEqual( ); - void testEWStringYesEmpty( ); - void testEWStringNoShorter( ); - void testEWStringNoLonger( ); - void testEWBinaryYes( ); - void testEWBinaryYesEqual( ); - void testEWBinaryYesEmpty( ); - void testEWBinaryNoShorter( ); - void testEWBinaryNoLonger( ); - void testEWWordString( ); - void testEWStringWord( ); - void testEWStringBad( ); - void testEWBadString( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdStringsTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdStringsTest::testConcatNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatBadArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat ( nope ) [ 01 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "binary array, text or numeric argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "[ 01 ]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatOneString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat \"string\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"string\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatStrings( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat \"str\" \"ing\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"string\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatStringWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat \"str\" ing )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"string\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatStringNumeric( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat \"i\" 2 \"l\" ( -to-long 2 ) \"f\" 1.2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"i2l2f1.2\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatStringBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat \"string\"\n[ 01 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text or numeric argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 1 ); - CPPUNIT_ASSERT( check( "\"string\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatOneBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat [ ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "[ ]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testConcatBinary( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -concat [ 01 ] [] [ 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "[ 01 02 ]" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdStringsTest::testSubstrNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBinaryNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr [ 01 02 03 04 05 06 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 33 ); - CPPUNIT_ASSERT( check( "[]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 1 to 2 blah )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 27 ); - CPPUNIT_ASSERT( check( "\"bc\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBinaryTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr [ 01 02 03 04 05 06 ] 1 to 2 blah )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 40 ); - CPPUNIT_ASSERT( check( "[]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBadTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr -12 1 to 2 blah )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "binary array or text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringOffset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"def\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBinaryOffset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr [ 01 02 03 04 05 06 ] 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "[ 04 05 06 ]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBadOffset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr 12 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "binary array or text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 11 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"\" \"\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringInvalid( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" -1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringHigh( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 7 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringOffsetLength( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 2 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"cde\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBinaryOffsetLength( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr [ 01 02 03 04 05 06 ] 2 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "[ 03 04 05 ]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringOffsetBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 2 nope )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "'to' or integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 22 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringOffsetToOffset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 2 to 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"cd\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBinaryOffsetToOffset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr [ 01 02 03 04 05 06 ] 2 to 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "[ 03 04 ]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringRangeInverted( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 3 to 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrBinaryRangeInverted( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr [ 01 02 03 04 05 06 ] 3 to 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "[ ]" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringOffsetBadOffset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 2 ot 3 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "'to' or integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 22 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrStringOffsetToBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 2 to meh )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 25 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrRangeInvalidStart( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" -2 to 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSubstrRangeInvalidEnd( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -substr \"abcdef\" 2 to -2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 25 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdStringsTest::testSplitNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"x\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 18 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"b\" 12 a b c )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 25 ); - CPPUNIT_ASSERT( check( "\"b\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitBadString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split 12 \"x\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"x\" 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 18 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitStringEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"\" \"...\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "\"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitStringStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"...\" x )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "integer argument or end of list expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 24 ); - CPPUNIT_ASSERT( check( "\"...\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitStringStringNegative( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"bab\" -1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "invalid argument value" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 24 ); - CPPUNIT_ASSERT( check( "\"b\" \"b\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitSingleNormal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"babaab\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"b\" \"b\" \"\" \"b\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitSingleStart( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"ab\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"\" \"b\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitSingleEnd( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"ba\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"b\" \"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitSingleNowhere( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"a\" \"nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"nope\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitMultiNormal( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"aba\" \"babaxabaababa\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"b\" \"x\" \"\" \"ba\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitMultiStart( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"aba\" \"abab\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"\" \"b\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitMultiEnd( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"aba\" \"baba\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"b\" \"\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitMultiNowhere( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"aba\" \"nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"nope\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitMultiLonger( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"moomoo\" \"nope\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"nope\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitLimitZero( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"x\" \"abababa\" 0 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"abababa\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitLimit( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"b\" \"abababa\" 2 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"a\" \"a\" \"aba\"" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSplitLimitGreater( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -str-split \"b\" \"abababa\" 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "\"a\" \"a\" \"a\" \"a\"" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdStringsTest::testSWNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"x\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with x y z )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringYes( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"abc\" \"abcdef\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringYesEqual( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"abc\" \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringYesEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"\" \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringNoShorter( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"abc\" \"defg\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringNoLonger( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"defg\" \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWBinaryYes( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with [ 00 ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWBinaryYesEqual( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with [ 00 01 02 ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWBinaryYesEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with [ ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWBinaryNoShorter( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with [ 01 ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWBinaryNoLonger( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with [ 00 01 02 ] [ 00 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWWordString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with abc \"abc d\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"abc\" abc-d )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with \"abc\" 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 22 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testSWBadString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -starts-with 12 \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "binary array or text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 16 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdStringsTest::testEWNotEnoughArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"x\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 18 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWTooManyArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with x y z )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 18 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringYes( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"def\" \"abcdef\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringYesEqual( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"abc\" \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringYesEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"\" \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringNoShorter( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"abc\" \"defg\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringNoLonger( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"defg\" \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWBinaryYes( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with [ 02 ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWBinaryYesEqual( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with [ 00 01 02 ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWBinaryYesEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with [ ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWBinaryNoShorter( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with [ 01 ] [ 00 01 02 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWBinaryNoLonger( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with [ 00 01 02 ] [ 00 ] )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWWordString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with d \"abc d\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringWord( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"c-d\" abc-d )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWStringBad( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with \"abc\" 12 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 20 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} - -void SRDPreprocCmdStringsTest::testEWBadString( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -ends-with 12 \"abc\" )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "binary array or text argument expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 14 ); - CPPUNIT_ASSERT( check( "0" , output ) ); -} diff --git a/tests/srd-preproc-cmd-variables.cc b/tests/srd-preproc-cmd-variables.cc deleted file mode 100644 index 5b1b654..0000000 --- a/tests/srd-preproc-cmd-variables.cc +++ /dev/null @@ -1,372 +0,0 @@ -#include "srd-preproc-cmd-common.hh" - - -class SRDPreprocCmdVariablesTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCmdVariablesTest ); - - CPPUNIT_TEST( testSetVarNoArgs ); - CPPUNIT_TEST( testSetVarBadName ); - CPPUNIT_TEST( testSetVarEmpty ); - CPPUNIT_TEST( testSetVarBasic ); - CPPUNIT_TEST( testSetVarList ); - CPPUNIT_TEST( testSetVarExisting ); - - CPPUNIT_TEST( testSetVarsNoNames ); - CPPUNIT_TEST( testSetVarsBadName ); - CPPUNIT_TEST( testSetVarsEmpty ); - CPPUNIT_TEST( testSetVarsMissing ); - CPPUNIT_TEST( testSetVarsMultiple ); - CPPUNIT_TEST( testSetVarsRest ); - CPPUNIT_TEST( testSetVarsRepeatName ); - CPPUNIT_TEST( testSetVarsExisting ); - CPPUNIT_TEST( testSetVarsExistingAndRepeated ); - - CPPUNIT_TEST( testUnsetNoArgs ); - CPPUNIT_TEST( testUnset ); - CPPUNIT_TEST( testUnsetMissing ); - CPPUNIT_TEST( testUnsetMultiple ); - CPPUNIT_TEST( testUnsetFromVarBeingUnset ); - - CPPUNIT_TEST( testGetEmpty ); - CPPUNIT_TEST( testGetBadArg ); - CPPUNIT_TEST( testGetMissing ); - CPPUNIT_TEST( testGetVar ); - CPPUNIT_TEST( testGetVars ); - CPPUNIT_TEST( testGetVarsWithErrors ); - - CPPUNIT_TEST( testListVariables ); - CPPUNIT_TEST( testListVariablesArgs ); - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testSetVarNoArgs( ); - void testSetVarBadName( ); - void testSetVarEmpty( ); - void testSetVarBasic( ); - void testSetVarList( ); - void testSetVarExisting( ); - - void testSetVarsNoNames( ); - void testSetVarsBadName( ); - void testSetVarsEmpty( ); - void testSetVarsMissing( ); - void testSetVarsMultiple( ); - void testSetVarsRest( ); - void testSetVarsRepeatName( ); - void testSetVarsExisting( ); - void testSetVarsExistingAndRepeated( ); - - void testUnsetNoArgs( ); - void testUnset( ); - void testUnsetMissing( ); - void testUnsetMultiple( ); - void testUnsetFromVarBeingUnset( ); - - void testGetEmpty( ); - void testGetBadArg( ); - void testGetMissing( ); - void testGetVar( ); - void testGetVars( ); - void testGetVarsWithErrors( ); - - void testListVariables( ); - void testListVariablesArgs( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCmdVariablesTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdVariablesTest::testSetVarNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "not enough arguments" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarBadName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set 1 )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "word or list expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set x )\n$x" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarBasic( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set x y )\n$x" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "y" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarList( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set x y z )\n$x" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "y z" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarExisting( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set x a )\n$x\n( -set x b )\n$x" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "duplicate variable name" , 3 , 3 ); - M_CKERR_( 1 , "previous error cause" , 3 , 8 ); - CPPUNIT_ASSERT( check( "a a" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdVariablesTest::testSetVarsNoNames( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "no variable names" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsBadName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( 1 ( ) ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "word expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - M_CKERR_( 2 , "word expected" , 1 , 3 ); - M_CKERR_( 3 , "previous error cause" , 1 , 12 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( a b ) )\n( $b ) ( $a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "()()" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsMissing( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( a b ) a )\n( $b ) ( $a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( ) ( a )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( a b ) a b )\n( $b ) ( $a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( b ) ( a )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsRest( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( a b ) a b c )\n( $b ) ( $a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( b c ) ( a )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsRepeatName( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set ( a a ) a b c )\n( $a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) ); - M_CKERR_( 0 , "duplicate variable name" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 10 ); - M_CKERR_( 2 , "unknown variable" , 2 , 3 ); - CPPUNIT_ASSERT( check( "( )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsExisting( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set b x )\n( -set ( a b ) u v )\n( $a )( $b )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) ); - M_CKERR_( 0 , "duplicate variable name" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 12 ); - M_CKERR_( 2 , "unknown variable" , 3 , 3 ); - CPPUNIT_ASSERT( check( "( )( x )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testSetVarsExistingAndRepeated( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set b x )\n( -set ( a b b a ) u v )\n( $a )( $b )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 5u , errors.size( ) ); - M_CKERR_( 0 , "duplicate variable name" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 10 ); - M_CKERR_( 2 , "duplicate variable name" , 2 , 3 ); - M_CKERR_( 3 , "previous error cause" , 2 , 12 ); - M_CKERR_( 4 , "unknown variable" , 3 , 3 ); - CPPUNIT_ASSERT( check( "( )( x )" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdVariablesTest::testUnsetNoArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unset ) " , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testUnset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -set a 1 )\n$a\n( -unset a )\n$a" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 4 , 1 ); - CPPUNIT_ASSERT( check( "1" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testUnsetMissing( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -unset a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testUnsetMultiple( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set ( a b c ) 1 2 3)\n" - "( -unset a c )\n" - "( $a $b $c )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 2 ) , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 3 , 3 ); - M_CKERR_( 1 , "unknown variable" , 3 , 9 ); - CPPUNIT_ASSERT( check( "( 2 )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testUnsetFromVarBeingUnset( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set ( c b a ) d c a b)\n" - "( -unset $a $b )\n" - "( $a $b $c )" , - errors ) ); - CPPUNIT_ASSERT_EQUAL( 3u , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 2 , 13 ); - M_CKERR_( 1 , "unknown variable" , 3 , 3 ); - M_CKERR_( 2 , "unknown variable" , 3 , 6 ); - CPPUNIT_ASSERT( check( "( d )" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdVariablesTest::testGetEmpty( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -get )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testGetBadArg( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -get 1 ( ) )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 4u , errors.size( ) ); - M_CKERR_( 0 , "word expected" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - M_CKERR_( 2 , "word expected" , 1 , 3 ); - M_CKERR_( 3 , "previous error cause" , 1 , 10 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testGetMissing( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -get a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 1 , 3 ); - M_CKERR_( 1 , "previous error cause" , 1 , 8 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testGetVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set a x)\n( -get a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "x" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testGetVars( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set ( a b c ) x y z w )\n( -get c b a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "z w y x" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testGetVarsWithErrors( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "(-set ( a b ) x y )\n( -get b c a )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 10 ); - CPPUNIT_ASSERT( check( "y x" , output ) ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCmdVariablesTest::testListVariables( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x )\n" - "( -set-macro y ( ( ) ) )\n" - "( -set f (-raw (() ((-ls-variables))) ))\n" - "( -bless f )\n" - "( ( -ls-variables ) )\n" - "( -scope\n" - "( -unset x )\n" - "( ( -ls-variables ) )\n" - ")\n" - "($f)\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "( x f ) ( f ) ( f )" , output ) ); -} - -void SRDPreprocCmdVariablesTest::testListVariablesArgs( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "( -set x )\n" - "( -ls-variables blah )\n" - , errors ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - M_CKERR_( 0 , "too many arguments" , 2 , 3 ); - M_CKERR_( 1 , "previous error cause" , 2 , 17 ); - CPPUNIT_ASSERT( check( "x" , output ) ); -} diff --git a/tests/srd-preproc-core.cc b/tests/srd-preproc-core.cc deleted file mode 100644 index 1395f3b..0000000 --- a/tests/srd-preproc-core.cc +++ /dev/null @@ -1,245 +0,0 @@ -#include -#include -#include -#include -using namespace lw; - - -class SRDPreprocCoreTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocCoreTest ); - CPPUNIT_TEST( testEmptyInput ); - CPPUNIT_TEST( testBasicInput ); - CPPUNIT_TEST( testCommentsSkipped ); - CPPUNIT_TEST( testCommandWordInInput ); - CPPUNIT_TEST( testBadCommand ); - CPPUNIT_TEST( testBadVariable ); - CPPUNIT_TEST( testUnterminatedLists ); - CPPUNIT_TEST( testTooManyErrorsInside ); - CPPUNIT_TEST( testTooManyErrorsAtEnd ); - CPPUNIT_TEST_SUITE_END( ); - - public: - void testEmptyInput( ); - void testBasicInput( ); - void testCommentsSkipped( ); - void testCommandWordInInput( ); - void testBadCommand( ); - void testBadVariable( ); - void testUnterminatedLists( ); - void testTooManyErrorsInside( ); - void testTooManyErrorsAtEnd( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocCoreTest ); - -/*----------------------------------------------------------------------------*/ - -// M_PRINTERR_( index ) - Print an error message -#define M_PRINTERR_( IDX ) \ - do { \ - auto const& _e( errors[ IDX ] ); \ - char err[ _e.error( ).size( ) + 1 ]; \ - err[ sizeof( err ) - 1 ] = 0; \ - memcpy( err , _e.error( ).data( ) , \ - sizeof( err ) - 1 ); \ - printf( "ERR %s l. %u c. %lu\n" , err , \ - _e.location( ).line( ) , \ - _e.location( ).character( ) ); \ - } while ( 0 ) - -// M_CKERR_( index , string , line , character ) - Check an error -#define M_CKERR_( IDX , STR , L , C ) \ - do { \ - auto const& _e( errors[ IDX ] ); \ - CPPUNIT_ASSERT( T_String( STR ) == _e.error( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( L ) , \ - _e.location( ).line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( C ) , \ - _e.location( ).character( ) ); \ - } while ( 0 ) - -namespace { - -T_SRDList process( - char const* const input , - T_SRDErrors& errors , - const bool clearFlushToken = true ) -{ - T_SRDMemoryTarget mt( false ); - mt.clearFlushToken( clearFlushToken ); - mt.start( errors ); - - T_SRDPreprocessorConfig cmd; - cmd.addBuiltinCommands( ); - T_SRDPreprocessor pp( cmd , mt ); - T_SRDLexer lexer( T_String( "test" ) , errors , pp ); - pp.start( errors ); - char const* ptr = input; - while ( *ptr != 0 ) { - lexer.processCharacter( *ptr ++ ); - } - lexer.processEnd( ); - mt.end( errors ); - - return mt.list( ); -} - -bool checkMatch( T_SRDList const& expected , T_SRDList const& actual ) -{ - const uint32_t nExpected( expected.size( ) ); - const uint32_t nActual( actual.size( ) ); - - bool ok( nExpected == nActual ); - const uint32_t nCheck( std::min( nExpected , nActual ) ); - for ( uint32_t i = 0 ; i < nCheck ; i ++ ) { - T_SRDToken const& tExpected( expected[ i ] ); - T_SRDToken const& tActual( actual[ i ] ); - if ( tExpected.type( ) != tActual.type( ) ) { - std::cerr << "Expected token at " - << tExpected.location( ).line( ) << ":" - << tExpected.location( ).character( ) - << " has type " << int( tExpected.type( ) ) << "; actual token has type " - << int( tActual.type( ) ) << "\n"; - ok = false; - } else if ( tExpected.stringValue( ) != tActual.stringValue( ) ) { - std::cerr << "Expected token at " - << tExpected.location( ).line( ) << ":" - << tExpected.location( ).character( ) - << " has different text\n"; - ok = false; - } - } - - if ( nExpected != nActual ) { - std::cerr << "List size mismatch (" << nExpected << " expected, " - << nActual << " found)\n"; - } - return ok; -} - -bool check( char const* expected , T_SRDList const& actual ) -{ - T_SRDMemoryTarget mt( false ); - T_SRDErrors errors; - T_SRDLexer lexer( T_String( "expected" ) , errors , mt ); - mt.start( errors ); - char const* ptr = expected; - while ( *ptr != 0 ) { - lexer.processCharacter( *ptr ++ ); - } - lexer.processEnd( ); - - return checkMatch( mt.list( ) , actual ); -} - -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocCoreTest::testEmptyInput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCoreTest::testBasicInput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "this is a simple test 123 \"yes\" ( a test )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "this is a simple test 123 \"yes\" ( a test )" , output ) ); -} - -void SRDPreprocCoreTest::testCommentsSkipped( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "a {comment!} ( is #skipped!\n)" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "a ( is )" , output ) ); -} - -void SRDPreprocCoreTest::testCommandWordInInput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "-blah" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 0 ) , errors.size( ) ); - CPPUNIT_ASSERT( check( "-blah" , output ) ); -} - -void SRDPreprocCoreTest::testBadCommand( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( -blah )" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unknown command" , 1 , 3 ); - CPPUNIT_ASSERT( check( "( -blah )" , output ) ); -} - -void SRDPreprocCoreTest::testBadVariable( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "$blah does not exist" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 1 ) , errors.size( ) ); - M_CKERR_( 0 , "unknown variable" , 1 , 1 ); - CPPUNIT_ASSERT( check( "does not exist" , output ) ); -} - -void SRDPreprocCoreTest::testUnterminatedLists( ) -{ - T_SRDErrors errors; - T_SRDList output( process( "( ( ) ( (" , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( 3 ) , errors.size( ) ); - M_CKERR_( 0 , "unterminated list" , 1 , 1 ); - M_CKERR_( 1 , "unterminated list" , 1 , 7 ); - M_CKERR_( 2 , "unterminated list" , 1 , 9 ); - CPPUNIT_ASSERT( check( "( ( ) ( ( ) ) )" , output ) ); -} - -namespace { - -T_StringBuilder RepeatError_( char const* string ) -{ - T_StringBuilder sb; - for ( uint32_t i = 0 ; i < T_SRDErrors::MAX_ERRORS * 2 ; i ++ ) { - if ( i > 0 ) { - sb << ' '; - } - sb << string; - } - sb << " x" << '\0'; - return sb; -} - -} - -void SRDPreprocCoreTest::testTooManyErrorsInside( ) -{ - T_StringBuilder input( RepeatError_( "$x" ) ); - T_SRDErrors errors; - T_SRDList output( process( input.data( ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( T_SRDErrors::MAX_ERRORS + 1 ) , errors.size( ) ); - M_CKERR_( T_SRDErrors::MAX_ERRORS , "too many errors" , 1 , T_SRDErrors::MAX_ERRORS * 3 - 2 ); - CPPUNIT_ASSERT( check( "" , output ) ); -} - -void SRDPreprocCoreTest::testTooManyErrorsAtEnd( ) -{ - T_StringBuilder input( RepeatError_( "(" ) ); - T_StringBuilder expectedOutput; - for ( uint32_t i = 0 ; i < T_SRDErrors::MAX_ERRORS * 2 ; i ++ ) { - expectedOutput << '('; - } - expectedOutput << 'x'; - for ( uint32_t i = 0 ; i < T_SRDErrors::MAX_ERRORS * 2 ; i ++ ) { - expectedOutput << ')'; - } - expectedOutput << '\0'; - - T_SRDErrors errors; - T_SRDList output( process( input.data( ) , errors ) ); - CPPUNIT_ASSERT_EQUAL( uint32_t( T_SRDErrors::MAX_ERRORS + 1 ) , errors.size( ) ); - M_CKERR_( T_SRDErrors::MAX_ERRORS , "too many errors" , 1 , T_SRDErrors::MAX_ERRORS * 2 - 1 ); - CPPUNIT_ASSERT( check( expectedOutput.data( ) , output ) ); -} diff --git a/tests/srd-preproc-location.hh b/tests/srd-preproc-location.hh deleted file mode 100644 index bd66621..0000000 --- a/tests/srd-preproc-location.hh +++ /dev/null @@ -1,133 +0,0 @@ -#ifndef TESTS_SRDPREPROCLOCATION_H_ -#define TESTS_SRDPREPROCLOCATION_H_ - -#include -#include -#include -#include -#include -using namespace lw; - - -namespace { - -inline T_SRDLocationChaining const* NextChain_( - T_SRDLocation const* from ) noexcept -{ - return (from && from->isChained( ) ) ? &from->chaining( ) : nullptr; -} - -uint32_t LocationDepth_( - const RPC_SRDLocation location ) noexcept -{ - uint32_t depth( 0 ); - auto lc( NextChain_( location ) ); - while ( lc ) { - depth ++; - lc = NextChain_( RPC_SRDLocation( lc->location ) ); - } - return depth; -} - -uint32_t ErrorDepth_( - T_SRDErrors const& errors , - const size_t index ) noexcept -{ - auto const& error( errors[ index ] ); - return LocationDepth_( &error.location( ) ); -} - -uint32_t TokenDepth_( - T_SRDList const& tokens , - const size_t index ) noexcept -{ - auto const& tok( tokens[ index ] ); - assert( tok.hasLocation( ) ); - return LocationDepth_( &tok.location( ) ); -} - -T_SRDLocationChaining const& GetChain_( - RPC_SRDLocation const& top , - uint32_t depth ) noexcept -{ - auto lc( NextChain_( top ) ); - assert( lc ); - while ( depth ) { - depth --; - lc = NextChain_( RPC_SRDLocation( lc->location ) ); - assert( lc ); - } - return *lc; -} - -void PrintLoc_( RPC_SRDLocation location ) noexcept -{ - printf( "at %s, l. %d c. %lu\n" , location->source( ).toOSString( ).data( ) , - location->line( ) , location->character( ) ); - if ( location->isChained( ) ) { - auto const& chain( location->chaining( ) ); - printf( "\tChain type %d, depth %d, " , - int( chain.circumstances ) , chain.depth ); - PrintLoc_( RPC_SRDLocation( chain.location ) ); - } -} - -} - -#define M_CKTOKDEPTH_( IDX , DEPTH ) \ - CPPUNIT_ASSERT_EQUAL( uint32_t( DEPTH ) , TokenDepth_( output , IDX ) ) - -#define M_CKTOKLOC_( IDX , NAME , LINE , CHAR ) \ - do { \ - auto const& loc( output[ IDX ].location( ) ); \ - CPPUNIT_ASSERT( T_String{ NAME } == loc.source( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , loc.line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , loc.character( ) ); \ - } while ( 0 ) - -#define M_CKTOKFULL_( IDX , NAME , LINE , CHAR , DEPTH ) \ - do { \ - auto const& loc( output[ IDX ].location( ) ); \ - CPPUNIT_ASSERT( T_String{ NAME } == loc.source( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , loc.line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , loc.character( ) ); \ - M_CKTOKDEPTH_( IDX , DEPTH ); \ - } while ( 0 ) - -#define M_CKTOKCHAIN_( IDX , DEPTH , HOW , NAME , LINE , CHAR , REC ) \ - do { \ - auto const& chain( GetChain_( &output[ IDX ].location( ) , DEPTH ) ); \ - CPPUNIT_ASSERT( E_SRDLocationChaining::HOW == chain.circumstances ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( REC ) , chain.depth ); \ - CPPUNIT_ASSERT( T_String{ NAME } == chain.location->source( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , chain.location->line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , chain.location->character( ) ); \ - } while ( 0 ) - - -#define M_CKERRDEPTH_( IDX , DEPTH ) \ - CPPUNIT_ASSERT_EQUAL( uint32_t( DEPTH ) , ErrorDepth_( errors , IDX ) ) - -#define M_CKERRFULL_( IDX , TEXT , DETAILS , NAME , LINE , CHAR , DEPTH ) \ - do { \ - CPPUNIT_ASSERT( T_String{ TEXT } == errors[ IDX ].error( ) ); \ - CPPUNIT_ASSERT_EQUAL( bool( DETAILS ) , errors[ IDX ].isDetails( ) ); \ - auto const& loc( errors[ IDX ].location( ) ); \ - CPPUNIT_ASSERT( T_String{ NAME } == loc.source( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , loc.line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , loc.character( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( DEPTH ) , ErrorDepth_( errors , IDX ) ); \ - } while ( 0 ) - -#define M_CKERRCHAIN_( IDX , DEPTH , HOW , NAME , LINE , CHAR , REC ) \ - do { \ - auto const& chain( GetChain_( &errors[ IDX ].location( ) , DEPTH ) ); \ - CPPUNIT_ASSERT( E_SRDLocationChaining::HOW == chain.circumstances ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( REC ) , chain.depth ); \ - CPPUNIT_ASSERT( T_String{ NAME } == chain.location->source( ) ); \ - CPPUNIT_ASSERT_EQUAL( uint32_t( LINE ) , chain.location->line( ) ); \ - CPPUNIT_ASSERT_EQUAL( size_t( CHAR ) , chain.location->character( ) ); \ - } while ( 0 ) - - -#endif // TESTS_SRDPREPROCLOCATION_H_ diff --git a/tests/srd-preproc-tracking.cc b/tests/srd-preproc-tracking.cc deleted file mode 100644 index 64cf5f9..0000000 --- a/tests/srd-preproc-tracking.cc +++ /dev/null @@ -1,676 +0,0 @@ -#include "srd-preproc-cmd-common.hh" -#include "srd-preproc-location.hh" -using namespace lw; - - -class SRDPreprocTrackingTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( SRDPreprocTrackingTest ); - - CPPUNIT_TEST( testTopLevel ); - - CPPUNIT_TEST( testVar ); - CPPUNIT_TEST( testVarGet ); - - CPPUNIT_TEST( testCall ); - CPPUNIT_TEST( testCalls ); - CPPUNIT_TEST( testCallRecursive ); - - CPPUNIT_TEST( testEval ); - CPPUNIT_TEST( testEvalCalls ); - - CPPUNIT_TEST( testCommandOutput ); - -#if 0 - CPPUNIT_TEST( testMacroBody ); - CPPUNIT_TEST( testMacroBodyCall ); - CPPUNIT_TEST( testMacroBodyEval ); - CPPUNIT_TEST( testCallMacroBody ); - CPPUNIT_TEST( testEvalMacroBody ); - - CPPUNIT_TEST( testMacroOutput ); - CPPUNIT_TEST( testMacroOutputCall ); - CPPUNIT_TEST( testMacroOutputEval ); - CPPUNIT_TEST( testCallMacroOutput ); - CPPUNIT_TEST( testEvalMacroOutput ); - -#endif -// CPPUNIT_TEST( testErrorTopLevel ); -#if 0 - CPPUNIT_TEST( testErrorCall ); -#endif - - CPPUNIT_TEST_SUITE_END( ); - - public: - void testTopLevel( ); - - void testVar( ); - void testVarGet( ); - - void testCall( ); - void testCalls( ); - void testCallRecursive( ); - - void testEval( ); - void testEvalCalls( ); - - void testCommandOutput( ); - -#if 0 - void testMacroBody( ); - void testMacroBodyCall( ); - void testMacroBodyEval( ); - void testCallMacroBody( ); - void testEvalMacroBody( ); - - void testMacroOutput( ); - void testMacroOutputCall( ); - void testMacroOutputEval( ); - void testCallMacroOutput( ); - void testEvalMacroOutput( ); - -#endif - void testErrorTopLevel( ); -#if 0 - void testErrorCall( ); -#endif -}; -CPPUNIT_TEST_SUITE_REGISTRATION( SRDPreprocTrackingTest ); - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testTopLevel( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "a\n" - "(-scope b)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "a b" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 0 ); - M_CKTOKLOC_( 0 , "test" , 1 , 1 ); - M_CKTOKDEPTH_( 1 , 0 ); - M_CKTOKLOC_( 1 , "test" , 2 , 9 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testVar( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set var value)\n" - "$var\n" - , errors ) ); - CPPUNIT_ASSERT( check( "value" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "$var" , 0 , 0 ); - M_CKTOKCHAIN_( 0 , 0 , SUBSTITUTED , "test" , 2 , 1 , 0 ); -} - -void SRDPreprocTrackingTest::testVarGet( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set (var vn) value var)\n" - "(-get var $vn)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "value value" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "$var" , 0 , 0 ); - M_CKTOKCHAIN_( 0 , 0 , SUBSTITUTED , "test" , 2 , 2 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "$var" , 0 , 0 ); - M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 2 , 2 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testCall( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( () b )))\n" - "(-bless fn)\n" - "a ($fn)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "a b" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 0 ); - M_CKTOKLOC_( 0 , "test" , 3 , 1 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "test" , 1 , 21 ); - M_CKTOKCHAIN_( 1 , 0 , CALLED , "test" , 3 , 4 , 0 ); -} - -void SRDPreprocTrackingTest::testCalls( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set ( fn1 fn2 ) (-raw\n" - "((d)\n" - "I ($fn2 $d) )\n" - "((d)\n" - "got $d)\n" - "))\n" - "(-bless fn1 fn2)\n" - "($fn1 it)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "I got it" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test" , 3 , 1 ); - M_CKTOKCHAIN_( 0 , 0 , CALLED , "test" , 8 , 2 , 0 ); - M_CKTOKDEPTH_( 1 , 2 ); - M_CKTOKLOC_( 1 , "test" , 5 , 1 ); - M_CKTOKCHAIN_( 1 , 0 , CALLED , "test" , 3 , 4 , 0 ); - M_CKTOKCHAIN_( 1 , 1 , CALLED , "test" , 8 , 2 , 0 ); - M_CKTOKDEPTH_( 2 , 3 ); - M_CKTOKLOC_( 2 , "$d" , 0 , 0 ); - M_CKTOKCHAIN_( 2 , 0 , SUBSTITUTED , "test" , 5 , 5 , 0 ); - M_CKTOKCHAIN_( 2 , 1 , CALLED , "test" , 3 , 4 , 0 ); - M_CKTOKCHAIN_( 2 , 2 , CALLED , "test" , 8 , 2 , 0 ); -} - -void SRDPreprocTrackingTest::testCallRecursive( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( (d)\n" - "$d\n" - "(-if (-gt $d 0) (\n" - "($fn (-sub $d 1))\n" - ")))))\n" - "(-bless fn)\n" - "($fn 6)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "6 5 4 3 2 1 0" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 2 ); - M_CKTOKCHAIN_( 0 , 0 , SUBSTITUTED , "test" , 2 , 1 , 0 ); - M_CKTOKCHAIN_( 0 , 1 , CALLED , "test" , 7 , 2 , 0 ); - - for ( auto i = 1u ; i < 7 ; i ++ ) { - M_CKTOKDEPTH_( i , 3 ); - M_CKTOKCHAIN_( i , 0 , SUBSTITUTED , "test" , 2 , 1 , 0 ); - M_CKTOKCHAIN_( i , 1 , CALLED , "test" , 4 , 2 , i - 1 ); - M_CKTOKCHAIN_( i , 2 , CALLED , "test" , 7 , 2 , 0 ); - } -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testEval( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set (x y f)\n" - "(-raw $y)\n" - "x\n" - "(() (-raw a (-raw $y) b))\n" - ")\n" - "(-bless f)\n" - "(-eval x $y $x ($f))\n" - , errors ) ); - CPPUNIT_ASSERT( check( "x x x a x b" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 0 ); - M_CKTOKLOC_( 0 , "test" , 7 , 8 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "$y" , 0 , 0 ); - M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 7 , 10 , 0 ); - M_CKTOKDEPTH_( 2 , 2 ); - M_CKTOKLOC_( 2 , "$y" , 0 , 0 ); - M_CKTOKCHAIN_( 2 , 0 , SUBSTITUTED , "$x" , 0 , 0 , 0 ); - M_CKTOKCHAIN_( 2 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); - M_CKTOKDEPTH_( 3 , 1 ); - M_CKTOKLOC_( 3 , "test" , 4 , 11 ); - M_CKTOKCHAIN_( 3 , 0 , CALLED , "test" , 7 , 17 , 0 ); - M_CKTOKDEPTH_( 4 , 2 ); - M_CKTOKLOC_( 4 , "$y" , 0 , 0 ); - M_CKTOKCHAIN_( 4 , 0 , SUBSTITUTED , "test" , 4 , 19 , 0 ); - M_CKTOKCHAIN_( 4 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); - M_CKTOKDEPTH_( 5 , 1 ); - M_CKTOKLOC_( 5 , "test" , 4 , 23 ); - M_CKTOKCHAIN_( 5 , 0 , CALLED , "test" , 7 , 17 , 0 ); -} - -void SRDPreprocTrackingTest::testEvalCalls( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set (x y f)\n" - "(-raw ($f 2))\n" - "(-raw $x)\n" - "(-raw ((x) a $x b))\n" - ")\n" - "(-bless f)\n" - "(-eval ($f 1) $x $y $x)\n" - , errors ) ); -#if 0 - printf( "\n\n" ); - for ( auto i = 0u ; i < output.size( ) ; i ++ ) { - PrintLoc_( &output[ i ].location( ) ); - printf( "\n" ); - } -#endif - CPPUNIT_ASSERT( check( "a 1 b a 2 b ($f 2) a 2 b" , output ) ); - - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "test" , 4 , 12 ); - M_CKTOKCHAIN_( 0 , 0 , CALLED , "test" , 7 , 9 , 0 ); - M_CKTOKDEPTH_( 1 , 2 ); - M_CKTOKLOC_( 1 , "$x" , 0 , 0 ); - M_CKTOKCHAIN_( 1 , 0 , SUBSTITUTED , "test" , 4 , 14 , 0 ); - M_CKTOKCHAIN_( 1 , 1 , CALLED , "test" , 7 , 9 , 0 ); - M_CKTOKDEPTH_( 2 , 1 ); - M_CKTOKLOC_( 2 , "test" , 4 , 17 ); - M_CKTOKCHAIN_( 2 , 0 , CALLED , "test" , 7 , 9 , 0 ); - - M_CKTOKDEPTH_( 3 , 2 ); - M_CKTOKLOC_( 3 , "test" , 4 , 12 ); - M_CKTOKCHAIN_( 3 , 0 , CALLED , "$x" , 0 , 1 , 0 ); - M_CKTOKCHAIN_( 3 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); - M_CKTOKDEPTH_( 4 , 3 ); - M_CKTOKLOC_( 4 , "$x" , 0 , 0 ); - M_CKTOKCHAIN_( 4 , 0 , SUBSTITUTED , "test" , 4 , 14 , 0 ); - M_CKTOKCHAIN_( 4 , 1 , CALLED , "$x" , 0 , 1 , 0 ); - M_CKTOKCHAIN_( 4 , 2 , EVALUATED , "test" , 7 , 2 , 0 ); - M_CKTOKDEPTH_( 5 , 2 ); - M_CKTOKLOC_( 5 , "test" , 4 , 17 ); - M_CKTOKCHAIN_( 5 , 0 , CALLED , "$x" , 0 , 1 , 0 ); - M_CKTOKCHAIN_( 5 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); - - for ( auto i = 0u ; i < 4 ; i ++ ) { - M_CKTOKDEPTH_( i + 6 , 2 ); - M_CKTOKLOC_( i + 6 , "$x" , 0 , i ); - M_CKTOKCHAIN_( i + 6 , 0 , SUBSTITUTED , "$y" , 0 , 0 , 0 ); - M_CKTOKCHAIN_( i + 6 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); - } - - M_CKTOKDEPTH_( 10 , 2 ); - M_CKTOKLOC_( 10 , "test" , 4 , 12 ); - M_CKTOKCHAIN_( 10 , 0 , CALLED , "$x" , 0 , 1 , 0 ); - M_CKTOKCHAIN_( 10 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); - M_CKTOKDEPTH_( 11 , 3 ); - M_CKTOKLOC_( 11 , "$x" , 0 , 0 ); - M_CKTOKCHAIN_( 11 , 0 , SUBSTITUTED , "test" , 4 , 14 , 0 ); - M_CKTOKCHAIN_( 11 , 1 , CALLED , "$x" , 0 , 1 , 0 ); - M_CKTOKCHAIN_( 11 , 2 , EVALUATED , "test" , 7 , 2 , 0 ); - M_CKTOKDEPTH_( 12 , 2 ); - M_CKTOKLOC_( 12 , "test" , 4 , 17 ); - M_CKTOKCHAIN_( 12 , 0 , CALLED , "$x" , 0 , 1 , 0 ); - M_CKTOKCHAIN_( 12 , 1 , EVALUATED , "test" , 7 , 2 , 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testCommandOutput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-add 1 2)\n" - "(-is-set x)\n" - "(-type-of w)\n" - "(-eq a b)\n" - "(-to-string x \"x\")\n" - "(-length abcdef)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "3 0 word 0 \"x\" \"x\" 6" , output ) ); - CPPUNIT_ASSERT_EQUAL( 0u , errors.size( ) ); - - M_CKTOKDEPTH_( 0 , 1 ); - M_CKTOKLOC_( 0 , "-add" , 0 , 0 ); - M_CKTOKCHAIN_( 0 , 0 , GENERATED , "test" , 1 , 2 , 0 ); - M_CKTOKDEPTH_( 1 , 1 ); - M_CKTOKLOC_( 1 , "-is-set" , 0 , 0 ); - M_CKTOKCHAIN_( 1 , 0 , GENERATED , "test" , 2 , 2 , 0 ); - M_CKTOKDEPTH_( 2 , 1 ); - M_CKTOKLOC_( 2 , "-type-of" , 0 , 0 ); - M_CKTOKCHAIN_( 2 , 0 , GENERATED , "test" , 3 , 2 , 0 ); - M_CKTOKDEPTH_( 3 , 1 ); - M_CKTOKLOC_( 3 , "-eq" , 0 , 0 ); - M_CKTOKCHAIN_( 3 , 0 , GENERATED , "test" , 4 , 2 , 0 ); - M_CKTOKDEPTH_( 4 , 1 ); - M_CKTOKLOC_( 4 , "-to-string" , 0 , 0 ); - M_CKTOKCHAIN_( 4 , 0 , GENERATED , "test" , 5 , 2 , 0 ); - M_CKTOKDEPTH_( 5 , 0 ); - M_CKTOKLOC_( 5 , "test" , 5 , 15 ); - M_CKTOKDEPTH_( 6 , 1 ); - M_CKTOKLOC_( 6 , "-length" , 0 , 0 ); - M_CKTOKCHAIN_( 6 , 0 , GENERATED , "test" , 6 , 2 , 0 ); -} - -#if 0 -void SRDPreprocTrackingTest::testCallRecursive( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( (d)\n" - "(-if $d (\n" - "($fn (-sub $d 1))\n" - ") (\n" - "(-error)\n" - ")))))\n" - "(-bless fn)\n" - "($fn 6)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 5 , 1 ); - M_CKERRDEPTH_( 0 , 2 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 3 , 1 , 6 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 8 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testCalls( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn1 (-raw ( (d)\n" - "(-if $d (\n" - "($fn1 (-sub $d 1))\n" - ") (\n" - "($fn2 4)\n" - ")))))\n" - "(-set fn2 (-raw ( (d)\n" - "(-if $d (\n" - "($fn2 (-sub $d 1))\n" - ") (\n" - "(-error)\n" - ")))))\n" - "(-bless fn1 fn2)\n" - "($fn1 6)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 11 , 1 ); - M_CKERRDEPTH_( 0 , 4 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 9 , 1 , 4 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 5 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::CALLED , 3 , 1 , 6 ); - M_CKERRCHAIN_( 0 , 3 , E_SRDLocationChaining::CALLED , 14 , 1 , 1 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testEval( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-eval\n" - "( (-raw -error ) )\n" - ")\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 2 , 1 ); - M_CKERRDEPTH_( 0 , 1 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::EVALUATED , 1 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testEvalCall( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( (d)\n" - "(-if $d (\n" - "($fn (-sub $d 1))\n" - ") (\n" - "(-error)\n" - ")))))\n" - "(-bless fn)\n" - "(-eval (-raw ($fn 6)))\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 5 , 1 ); - M_CKERRDEPTH_( 0 , 3 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 3 , 1 , 6 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 8 , 14 , 1 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::EVALUATED , 8 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testCallEval( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( (d)\n" - "(-if $d (\n" - "($fn (-sub $d 1))\n" - ") (\n" - "(-eval (-raw (-error)))\n" - ")))))\n" - "(-bless fn)\n" - "($fn 6)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 5 , 14 ); - M_CKERRDEPTH_( 0 , 3 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::EVALUATED , 5 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 3 , 1 , 6 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::CALLED , 8 , 1 , 1 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testMacroBody( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-error) )))\n" - "(m)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 26 ); - M_CKERRDEPTH_( 0 , 1 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 2 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testMacroBodyCall( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( () (-error) )))\n" - "(-bless fn)\n" - "(-set-macro m (-raw ( () ($fn) )))\n" - "(m)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 21 ); - M_CKERRDEPTH_( 0 , 2 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 3 , 26 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 4 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testMacroBodyEval( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-eval (-raw (-error))) )))\n" - "(m)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 39 ); - M_CKERRDEPTH_( 0 , 2 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::EVALUATED , 1 , 26 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 2 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testCallMacroBody( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-error) )))\n" - "(-set fn (-raw ( () (m))))\n" - "(-bless fn)\n" - "($fn)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 26 ); - M_CKERRDEPTH_( 0 , 2 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 2 , 21 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::CALLED , 4 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testEvalMacroBody( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-error) )))\n" - "(-eval (-raw (m)))\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 26 ); - M_CKERRDEPTH_( 0 , 2 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 2 , 14 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::EVALUATED , 2 , 1 , 1 ); -} - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testMacroOutput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-raw (-error)) )))\n" - "(m)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 32 ); - M_CKERRDEPTH_( 0 , 3 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::EVALUATED , 2 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::GENERATED , 1 , 32 , 1 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::CALLED , 2 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testMacroOutputCall( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set fn (-raw ( () (-error) )))\n" - "(-bless fn)\n" - "(-set-macro m (-raw ( () (-raw ($fn)) )))\n" - "(m)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 21 ); - M_CKERRDEPTH_( 0 , 4 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::CALLED , 3 , 32 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::EVALUATED , 4 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::GENERATED , 3 , 32 , 1 ); - M_CKERRCHAIN_( 0 , 3 , E_SRDLocationChaining::CALLED , 4 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testMacroOutputEval( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-raw\n" - "(-eval (-raw (-error)))\n" - ") )))\n" - "(m)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 2 , 14 ); - M_CKERRDEPTH_( 0 , 4 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::EVALUATED , 2 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::EVALUATED , 4 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::GENERATED , 2 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 3 , E_SRDLocationChaining::CALLED , 4 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testCallMacroOutput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-raw\n" - "(-error)\n" - ") )))\n" - "(-set fn (-raw ( () (m) )))\n" - "(-bless fn)\n" - "($fn)\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 2 , 1 ); - M_CKERRDEPTH_( 0 , 4 ); - M_CKERRCHAIN_( 0 , 0 , E_SRDLocationChaining::EVALUATED , 4 , 21 , 1 ); - M_CKERRCHAIN_( 0 , 1 , E_SRDLocationChaining::GENERATED , 2 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 2 , E_SRDLocationChaining::CALLED , 4 , 21 , 1 ); - M_CKERRCHAIN_( 0 , 3 , E_SRDLocationChaining::CALLED , 6 , 1 , 1 ); -} - -void SRDPreprocTrackingTest::testEvalMacroOutput( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-set-macro m (-raw ( () (-raw\n" - "(-error)\n" - ") )))\n" - "(-eval (-raw (m)))\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 1u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 2 , 1 ); - M_CKERRDEPTH_( 0 , 4 ); - M_CKERRCHAIN_( 0 , 0 , EVALUATED , 4 , 14 , 1 ); - M_CKERRCHAIN_( 0 , 1 , GENERATED , 2 , 1 , 1 ); - M_CKERRCHAIN_( 0 , 2 , CALLED , 4 , 14 , 1 ); - M_CKERRCHAIN_( 0 , 3 , EVALUATED , 4 , 1 , 1 ); -} -#endif - -/*----------------------------------------------------------------------------*/ - -void SRDPreprocTrackingTest::testErrorTopLevel( ) -{ - T_SRDErrors errors; - T_SRDList output( process( - "(-error)\n" - "(-scope (-error))\n" - , errors ) ); - CPPUNIT_ASSERT( check( "" , output ) ); - CPPUNIT_ASSERT_EQUAL( 2u , errors.size( ) ); - - M_CKERR_( 0 , "user error" , 1 , 2 ); - M_CKERRDEPTH_( 0 , 0 ); - - M_CKERR_( 1 , "user error" , 2 , 10 ); - M_CKERRDEPTH_( 1 , 0 ); -} diff --git a/tests/srd-text-writer.cc b/tests/srd-text-writer.cc index 2e90d32..d2586ad 100644 --- a/tests/srd-text-writer.cc +++ b/tests/srd-text-writer.cc @@ -1,8 +1,8 @@ -#include -#include +#include +#include #include #include -using namespace lw; +using namespace ebcl; class SRDTextWriterTest : public CppUnit::TestFixture diff --git a/tests/stream-file-input.cc b/tests/stream-file-input.cc deleted file mode 100644 index 70e2017..0000000 --- a/tests/stream-file-input.cc +++ /dev/null @@ -1,268 +0,0 @@ -#include -#include -using namespace lw; - -#if 0 - -/*= FileInputStreamTest =====================================================*/ - -class FileInputStreamTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( FileInputStreamTest ); - CPPUNIT_TEST( testInitRealFile ); - CPPUNIT_TEST( testInitBadFile ); - - CPPUNIT_TEST( testOpenRealFile ); - CPPUNIT_TEST( testOpenBadFile ); - CPPUNIT_TEST( testClose ); - - CPPUNIT_TEST( testReadOpensFile ); - CPPUNIT_TEST( testReadAll ); - CPPUNIT_TEST( testReadPartial ); - - CPPUNIT_TEST( testSetPosOpensFile ); - CPPUNIT_TEST( testSetPosStart ); - CPPUNIT_TEST( testSetPosEnd ); - CPPUNIT_TEST( testSetPosEndBad ); - - CPPUNIT_TEST( testMoveOpensFile ); - CPPUNIT_TEST( testMoveForward ); - CPPUNIT_TEST( testMoveBack ); - CPPUNIT_TEST( testMoveBad ); - CPPUNIT_TEST_SUITE_END( ); - - T_String OK_FILE( ) - { - return T_String::Pooled( "tests/data/inputstream.txt" ); - } - - T_String BAD_FILE( ) - { - return T_String::Pooled( "tests/data/no_such_file.txt" ); - } - - char const* CONTENTS( ) - { - return "THIS IS A TEST\n"; - } - -public: - void testInitRealFile( ); - void testInitBadFile( ); - - void testOpenRealFile( ); - void testOpenBadFile( ); - void testClose( ); - - void testReadOpensFile( ); - void testReadAll( ); - void testReadPartial( ); - - void testSetPosOpensFile( ); - void testSetPosStart( ); - void testSetPosEnd( ); - void testSetPosEndBad( ); - - void testMoveOpensFile( ); - void testMoveForward( ); - void testMoveBack( ); - void testMoveBad( ); -}; -CPPUNIT_TEST_SUITE_REGISTRATION( FileInputStreamTest ); - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testInitRealFile( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - CPPUNIT_ASSERT( fis.path( ) == OK_FILE( ) ); - CPPUNIT_ASSERT( fis.canUseSize( ) ); - CPPUNIT_ASSERT( fis.canRead( ) ); - CPPUNIT_ASSERT( fis.size( ) == 0 ); - CPPUNIT_ASSERT( fis.position( ) == 0 ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testInitBadFile( ) -{ - T_FileInputStream fis( BAD_FILE( ) ); - CPPUNIT_ASSERT( fis.path( ) == BAD_FILE( ) ); - CPPUNIT_ASSERT( fis.canUseSize( ) ); - CPPUNIT_ASSERT( fis.canRead( ) ); - CPPUNIT_ASSERT( fis.size( ) == 0 ); - CPPUNIT_ASSERT( fis.position( ) == 0 ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testOpenRealFile( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - CPPUNIT_ASSERT( fis.size( ) == 15 ); - CPPUNIT_ASSERT( fis.position( ) == 0 ); - CPPUNIT_ASSERT( fis.isOpen( ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testOpenBadFile( ) -{ - T_FileInputStream fis( BAD_FILE( ) ); - try { - fis.open( ); - CPPUNIT_FAIL( "No exception thrown" ); - } catch ( X_StreamError const& e ) { - CPPUNIT_ASSERT( e.code( ) == E_StreamError::SYSTEM_ERROR ); - CPPUNIT_ASSERT( e.systemError( ) == ENOENT ); - } - CPPUNIT_ASSERT( fis.size( ) == 0 ); - CPPUNIT_ASSERT( fis.position( ) == 0 ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testClose( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - fis.close( ); - CPPUNIT_ASSERT( !fis.isOpen( ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 0 ) , fis.size( ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 0 ) , fis.position( ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testReadOpensFile( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - uint8_t x; - fis.read( &x , 0 ); - CPPUNIT_ASSERT( fis.isOpen( ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testReadAll( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - uint8_t buffer[ 1024 ]; - auto rv( fis.read( buffer , sizeof( buffer ) ) ); - CPPUNIT_ASSERT_EQUAL( fis.size( ) , rv ); - CPPUNIT_ASSERT_EQUAL( fis.size( ) , fis.position( ) ); - CPPUNIT_ASSERT( !memcmp( buffer , CONTENTS( ) , rv ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testReadPartial( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - uint8_t buffer[ 1024 ]; - auto rv( fis.read( buffer , 4 ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 4 ) , rv ); - CPPUNIT_ASSERT_EQUAL( size_t( 4 ) , fis.position( ) ); - CPPUNIT_ASSERT( !memcmp( buffer , CONTENTS( ) , 4 ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testSetPosOpensFile( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.position( 4 , false ); - CPPUNIT_ASSERT( fis.isOpen( ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testSetPosStart( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - fis.position( 4 , false ); - CPPUNIT_ASSERT_EQUAL( size_t( 4 ) , fis.position( ) ); - - uint8_t buffer[ 1024 ]; - auto rv( fis.read( buffer , 3 ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 3 ) , rv ); - CPPUNIT_ASSERT( !memcmp( buffer , CONTENTS( ) + 4 , 3 ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testSetPosEnd( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - fis.position( 4 , true ); - CPPUNIT_ASSERT_EQUAL( size_t( 11 ) , fis.position( ) ); - - uint8_t buffer[ 1024 ]; - auto rv( fis.read( buffer , 1024 ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 4 ) , rv ); - CPPUNIT_ASSERT( !memcmp( buffer , CONTENTS( ) + 11 , 4 ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testSetPosEndBad( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - CPPUNIT_ASSERT_THROW( fis.position( fis.size( ) + 1 , true ) , - X_StreamError ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testMoveOpensFile( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.move( 0 ); - CPPUNIT_ASSERT( fis.isOpen( ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testMoveForward( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - fis.move( 4 ); - CPPUNIT_ASSERT_EQUAL( size_t( 4 ) , fis.position( ) ); - - uint8_t buffer[ 1024 ]; - auto rv( fis.read( buffer , 3 ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 3 ) , rv ); - CPPUNIT_ASSERT( !memcmp( buffer , CONTENTS( ) + 4 , 3 ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testMoveBack( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - fis.position( 8 ); - fis.move( -4 ); - CPPUNIT_ASSERT_EQUAL( size_t( 4 ) , fis.position( ) ); - - uint8_t buffer[ 1024 ]; - auto rv( fis.read( buffer , 3 ) ); - CPPUNIT_ASSERT_EQUAL( size_t( 3 ) , rv ); - CPPUNIT_ASSERT( !memcmp( buffer , CONTENTS( ) + 4 , 3 ) ); -} - -/*---------------------------------------------------------------------------*/ - -void FileInputStreamTest::testMoveBad( ) -{ - T_FileInputStream fis( OK_FILE( ) ); - fis.open( ); - CPPUNIT_ASSERT_THROW( fis.move( -1 ) , X_StreamError ); -} - -#endif diff --git a/tests/vfs.cc b/tests/vfs.cc deleted file mode 100644 index 03be00b..0000000 --- a/tests/vfs.cc +++ /dev/null @@ -1,318 +0,0 @@ -#include -#include -using namespace lw; - - -/*= VFSPathTest ===============================================================*/ - -class VFSPathTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( VFSPathTest ); - CPPUNIT_TEST( testUnknown ); - CPPUNIT_TEST( testRoot ); - CPPUNIT_TEST( testAbsolute ); - CPPUNIT_TEST( testRelative ); - - CPPUNIT_TEST( testValid ); - CPPUNIT_TEST( testInvalid ); - - CPPUNIT_TEST( testDotDirs ); - CPPUNIT_TEST( testDotInNames ); - CPPUNIT_TEST( testLeadingDots ); - - CPPUNIT_TEST( testTrailingSlash ); - CPPUNIT_TEST( testExtraSlashes ); - - CPPUNIT_TEST( testEquals ); - CPPUNIT_TEST( testToString ); - CPPUNIT_TEST( testAppend ); - CPPUNIT_TEST( testNormalize ); - CPPUNIT_TEST_SUITE_END( ); - -public: - void testUnknown( ); - void testRoot( ); - void testAbsolute( ); - void testRelative( ); - - void testValid( ); - void testInvalid( ); - - void testDotDirs( ); - void testDotInNames( ); - void testLeadingDots( ); - - void testTrailingSlash( ); - void testExtraSlashes( ); - - void testEquals( ); - void testToString( ); - void testAppend( ); - void testNormalize( ); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION( VFSPathTest ); - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testUnknown( ) -{ - { - T_VFSPath path; - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::UNKNOWN ); - CPPUNIT_ASSERT( path.elements( ) == 0 ); - } - { - T_VFSPath path( "" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::UNKNOWN ); - CPPUNIT_ASSERT( path.elements( ) == 0 ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testRoot( ) -{ - T_VFSPath path( "/" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::ABSOLUTE ); - CPPUNIT_ASSERT( path.elements( ) == 0 ); -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testAbsolute( ) -{ - T_VFSPath path( "/this/is/a/test" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::ABSOLUTE ); - CPPUNIT_ASSERT( path.elements( ) == 4 ); - CPPUNIT_ASSERT( path[ 0 ] == "this" ); - CPPUNIT_ASSERT( path[ 1 ] == "is" ); - CPPUNIT_ASSERT( path[ 2 ] == "a" ); - CPPUNIT_ASSERT( path[ 3 ] == "test" ); -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testRelative( ) -{ - T_VFSPath path( "this/is/a/test" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::RELATIVE ); - CPPUNIT_ASSERT( path.elements( ) == 4 ); - CPPUNIT_ASSERT( path[ 0 ] == "this" ); - CPPUNIT_ASSERT( path[ 1 ] == "is" ); - CPPUNIT_ASSERT( path[ 2 ] == "a" ); - CPPUNIT_ASSERT( path[ 3 ] == "test" ); -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testValid( ) -{ - char const* const NAMES[] = { - "test" , "123" , "test-123" , "-test-123-" , "test_123" , "_" , "-" - }; - - for ( size_t i = 0 ; i < sizeof( NAMES ) / sizeof( NAMES[ 0 ] ) ; i ++ ) { - T_VFSPath path( NAMES[ i ] ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::RELATIVE ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testInvalid( ) -{ - char const* const NAMES[] = { - "bad name" , "bad\\name" , "bad\u00e9name" , "bad\x09name" , - "BadName" - }; - - for ( size_t i = 0 ; i < sizeof( NAMES ) / sizeof( NAMES[ 0 ] ) ; i ++ ) { - T_VFSPath path( NAMES[ i ] ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::INVALID ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testDotDirs( ) -{ - { - T_VFSPath path( "./.././test" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::RELATIVE ); - CPPUNIT_ASSERT( path.elements( ) == 4 ); - CPPUNIT_ASSERT( path[ 0 ] == "." ); - CPPUNIT_ASSERT( path[ 1 ] == ".." ); - CPPUNIT_ASSERT( path[ 2 ] == "." ); - CPPUNIT_ASSERT( path[ 3 ] == "test" ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testDotInNames( ) -{ - { - T_VFSPath path( "test.test/test...test/test." ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::RELATIVE ); - CPPUNIT_ASSERT( path.elements( ) == 3 ); - CPPUNIT_ASSERT( path[ 0 ] == "test.test" ); - CPPUNIT_ASSERT( path[ 1 ] == "test...test" ); - CPPUNIT_ASSERT( path[ 2 ] == "test." ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testLeadingDots( ) -{ - { - T_VFSPath path( ".test" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::INVALID ); - CPPUNIT_ASSERT( path.elements( ) == 1 ); - CPPUNIT_ASSERT( path[ 0 ] == ".test" ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testTrailingSlash( ) -{ - T_VFSPath path( "/this/is/a/test/" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::ABSOLUTE ); - CPPUNIT_ASSERT( path.elements( ) == 4 ); - CPPUNIT_ASSERT( path[ 0 ] == "this" ); - CPPUNIT_ASSERT( path[ 1 ] == "is" ); - CPPUNIT_ASSERT( path[ 2 ] == "a" ); - CPPUNIT_ASSERT( path[ 3 ] == "test" ); -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testExtraSlashes( ) -{ - T_VFSPath path( "///this////is//a////test///" ); - CPPUNIT_ASSERT( path.type( ) == E_VFSPathType::ABSOLUTE ); - CPPUNIT_ASSERT( path.elements( ) == 4 ); - CPPUNIT_ASSERT( path[ 0 ] == "this" ); - CPPUNIT_ASSERT( path[ 1 ] == "is" ); - CPPUNIT_ASSERT( path[ 2 ] == "a" ); - CPPUNIT_ASSERT( path[ 3 ] == "test" ); -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testEquals( ) -{ - const T_VFSPath PATHS[] = { - {} , ".bad" , "test" , "/test" , "this/is/a/test" - }; - const auto n( sizeof( PATHS ) / sizeof( PATHS[ 0 ] ) ); - - T_VFSPath copies[ n ]; - for ( size_t i = 0 ; i < n ; i ++ ) { - copies[ i ] = PATHS[ i ]; - } - - for ( size_t i = 0 ; i < n ; i ++ ) { - for ( size_t j = 0 ; j < n ; j ++ ) { - if ( i == j ) { - CPPUNIT_ASSERT( PATHS[ i ] == PATHS[ j ] ); - CPPUNIT_ASSERT( PATHS[ i ] == copies[ j ] ); - } else { - CPPUNIT_ASSERT( PATHS[ i ] != PATHS[ j ] ); - CPPUNIT_ASSERT( PATHS[ i ] != copies[ j ] ); - } - } - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testToString( ) -{ - char const* const PATHS[] = { - "/test" , "test" , "test/test" , "/test/test" , "" , ".bad" - }; - for ( size_t i = 0 ; i < sizeof( PATHS ) / sizeof( PATHS[ 0 ] ) ; i ++ ) { - T_VFSPath path( PATHS[ i ] ); - CPPUNIT_ASSERT( T_String( path ) == PATHS[ i ] ); - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testAppend( ) -{ - const T_VFSPath paths[] = { - "/test" , "test" , ".bad" , {} - }; - const E_VFSPathType combos[] = { - // Parent is absolute - E_VFSPathType::ABSOLUTE , E_VFSPathType::ABSOLUTE , - E_VFSPathType::INVALID , E_VFSPathType::UNKNOWN , - // Parent is relative - E_VFSPathType::RELATIVE , E_VFSPathType::RELATIVE , - E_VFSPathType::INVALID , E_VFSPathType::UNKNOWN , - // Parent is invalid - E_VFSPathType::INVALID , E_VFSPathType::INVALID , - E_VFSPathType::INVALID , E_VFSPathType::UNKNOWN , - // Parent is unknown - E_VFSPathType::UNKNOWN , E_VFSPathType::UNKNOWN , - E_VFSPathType::UNKNOWN , E_VFSPathType::UNKNOWN - }; - - int cid = 0; - for ( int i = 0 ; i < 4 ; i ++ ) { - for ( int j = 0 ; j < 4 ; j ++ , cid ++ ) { - T_VFSPath parent( paths[ i ] ) , child( paths[ j ] ); - T_VFSPath path( parent , child ); - //printf( "i = %d j = %d t = %d\n" , i , j , int( path.type( ) ) ); - CPPUNIT_ASSERT( path.type( ) == combos[ cid ] ); - if ( combos[ cid ] == E_VFSPathType::UNKNOWN ) { - CPPUNIT_ASSERT( path.elements( ) == 0 ); - } else { - CPPUNIT_ASSERT( path.elements( ) == parent.elements( ) + child.elements( ) ); - CPPUNIT_ASSERT( path[ 0 ] == parent[ 0 ] ); - CPPUNIT_ASSERT( path[ 1 ] == child[ 0 ] ); - } - } - } -} - -/*----------------------------------------------------------------------------*/ - -void VFSPathTest::testNormalize( ) -{ - const T_VFSPath INPUTS[] = { - {} , ".bad" , "/test" , "test" , - "./test" , - "/." , - "/.." , - "." , - ".." , - "wat/../wet/../wut" , - "wat/../.." , - "wat/.." , - "/wat/../.." - }; - const T_VFSPath EXPECTED[] = { - {} , {} , "/test" , "test" , - "test" , - "/" , - "/" , - "." , - ".." , - "wut" , - ".." , - "." , - "/" - }; - static_assert( sizeof( INPUTS ) / sizeof( INPUTS[ 0 ] ) - == sizeof( EXPECTED ) / sizeof( EXPECTED[ 0 ] ) , - "yo, your test sucks!" ); - - for ( size_t i = 0 ; i < sizeof( INPUTS ) / sizeof( INPUTS[ 0 ] ) ; i ++ ) { - CPPUNIT_ASSERT( T_String( INPUTS[ i ].normalize( ) ) == T_String( EXPECTED[ i ] ) ); - } -}