Finished importing the good bits from LW's library

This commit is contained in:
Emmanuel BENOîT 2017-11-01 23:21:01 +01:00
parent b9d77922ed
commit 4ab3dc1b29
82 changed files with 177 additions and 24084 deletions

View file

@ -5,9 +5,9 @@
#ifndef _H_EBCL_DYNLIB
#define _H_EBCL_DYNLIB
#include <lw/lib/Strings.hh>
#include <lw/lib/Utilities.hh>
namespace lw {
#include <ebcl/Strings.hh>
#include <ebcl/Utilities.hh>
namespace ebcl {
/*= DYNAMIC LIBRARY SUPPORT ==================================================*/
@ -45,4 +45,4 @@ M_CLASS_POINTERS( DynLib );
} // namespace lw
#endif // _H_EBCL_DYNLIB
#include <lw/lib/inline/DynLib.hh>
#include <ebcl/inline/DynLib.hh>

View file

@ -1,30 +0,0 @@
/******************************************************************************/
/* GAME'S MAIN LOOP ***********************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_GAMELOOP
#define _H_LW_LIB_GAMELOOP
#include <lw/lib/Messages.hh>
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

View file

@ -1,282 +0,0 @@
/******************************************************************************/
/* UI<=>GAME MESSAGES *********************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_MESSAGES
#define _H_LW_LIB_MESSAGES
#include <lw/lib/Strings.hh>
#include <lw/lib/Types.hh>
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 <lw/lib/inline/Messages.hh>

View file

@ -1,247 +0,0 @@
/******************************************************************************/
/* MODDING SYSTEM *************************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_MODS
#define _H_LW_LIB_MODS
#include <lw/lib/Log.hh>
#include <lw/lib/ModInterface.hh>
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 <lw/lib/inline/Mods.hh>

View file

@ -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

View file

@ -2,11 +2,11 @@
/* SRD - BINARY STORAGE *******************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDBINARY
#define _H_LW_LIB_SRDBINARY
#include <lw/lib/SRDIO.hh>
#include <lw/lib/HashIndex.hh>
namespace lw {
#ifndef _H_EBCL_SRDBINARY
#define _H_EBCL_SRDBINARY
#include <ebcl/SRDIO.hh>
#include <ebcl/HashIndex.hh>
namespace ebcl {
/*= WRITER ===================================================================*/
@ -74,5 +74,5 @@ T_SRDList SRDBinaryReadFrom( T_String const& name , A_InputStream& input , bool
} // namespace
#include <lw/lib/inline/SRDBinary.hh>
#endif // _H_LW_LIB_SRDBINARY
#include <ebcl/inline/SRDBinary.hh>
#endif // _H_EBCL_SRDBINARY

View file

@ -2,12 +2,12 @@
/* SRD - DATA *****************************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDDATA
#define _H_LW_LIB_SRDDATA
#include <lw/lib/Externals.hh>
#include <lw/lib/Strings.hh>
#include <lw/lib/Types.hh>
namespace lw {
#ifndef _H_EBCL_SRDDATA
#define _H_EBCL_SRDDATA
#include <ebcl/Externals.hh>
#include <ebcl/Strings.hh>
#include <ebcl/Types.hh>
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 <lw/lib/inline/SRDData.hh>
#endif // _H_LW_LIB_SRDDATA
#include <ebcl/inline/SRDData.hh>
#endif // _H_EBCL_SRDDATA

View file

@ -2,11 +2,11 @@
/* SRD - PARSER DEFINITIONS ***************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDDEFINITIONS
#define _H_LW_LIB_SRDDEFINITIONS
#include <lw/lib/SRDData.hh>
#include <lw/lib/HashTables.hh>
namespace lw {
#ifndef _H_EBCL_SRDDEFINITIONS
#define _H_EBCL_SRDDEFINITIONS
#include <ebcl/SRDData.hh>
#include <ebcl/HashTables.hh>
namespace ebcl {
/*= DEFINITION DATA ==========================================================*/
@ -317,5 +317,5 @@ T_SRDInputRule::T_SetContextExecutor OnExit( F_SRDHandler f );
} // namespace
#include <lw/lib/inline/SRDDefinitions.hh>
#endif // _H_LW_LIB_SRDDEFINITIONS
#include <ebcl/inline/SRDDefinitions.hh>
#endif // _H_EBCL_SRDDEFINITIONS

View file

@ -2,10 +2,10 @@
/* SRD - INPUT AND OUTPUT *****************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDIO
#define _H_LW_LIB_SRDIO
#include <lw/lib/SRDData.hh>
namespace lw {
#ifndef _H_EBCL_SRDIO
#define _H_EBCL_SRDIO
#include <ebcl/SRDData.hh>
namespace ebcl {
/*= INPUT / OUTPUT ABSTRACTIONS ==============================================*/
@ -183,5 +183,5 @@ M_CLASS_POINTERS( SRDWriterTarget );
} // namespace
#include <lw/lib/inline/SRDIO.hh>
#endif // _H_LW_LIB_SRDIO
#include <ebcl/inline/SRDIO.hh>
#endif // _H_EBCL_SRDIO

View file

@ -1,101 +0,0 @@
/******************************************************************************/
/* SRD - PREPROCESSOR COMMANDS ************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDPPCOMMANDS
#define _H_LW_LIB_SRDPPCOMMANDS
#include <lw/lib/SRDPreproc.hh>
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

View file

@ -1,11 +1,12 @@
/******************************************************************************/
/* SRD PARSER AND PREPROCESSOR ************************************************/
/* SRD PARSER *****************************************************************/
/******************************************************************************/
#pragma once
#include <lw/lib/SRDIO.hh>
#include <lw/lib/SRDParserConfig.hh>
namespace lw {
#ifndef _H_EBCL_SRDPARSER
#define _H_EBCL_SRDPARSER
#include <ebcl/SRDIO.hh>
#include <ebcl/SRDParserConfig.hh>
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

View file

@ -2,11 +2,11 @@
/* SRD - PARSER CONFIGURATION *************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDPARSERCONFIG
#define _H_LW_LIB_SRDPARSERCONFIG
#include <lw/lib/SRDDefinitions.hh>
#include <lw/lib/Types.hh>
namespace lw {
#ifndef _H_EBCL_SRDPARSERCONFIG
#define _H_EBCL_SRDPARSERCONFIG
#include <ebcl/SRDDefinitions.hh>
#include <ebcl/Types.hh>
namespace ebcl {
/*= PROCESSED PARSER CONFIGURATION ===========================================*/
@ -95,5 +95,5 @@ class X_SRDParserConfig : public std::exception
} // namespace
#include <lw/lib/inline/SRDParserConfig.hh>
#endif // _H_LW_LIB_SRDPARSERCONFIG
#include <ebcl/inline/SRDParserConfig.hh>
#endif // _H_EBCL_SRDPARSERCONFIG

View file

@ -2,10 +2,10 @@
/* SRD - TEXT STORAGE *********************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_SRDTEXT
#define _H_LW_LIB_SRDTEXT
#include <lw/lib/SRDIO.hh>
namespace lw {
#ifndef _H_EBCL_SRDTEXT
#define _H_EBCL_SRDTEXT
#include <ebcl/SRDIO.hh>
namespace ebcl {
/*= READER ===================================================================*/
@ -89,5 +89,5 @@ void SRDWriteAsText( A_OutputStream& output , T_SRDList const& data );
} // namespace
#include <lw/lib/inline/SRDText.hh>
#endif // _H_LW_LIB_SRDTEXT
#include <ebcl/inline/SRDText.hh>
#endif // _H_EBCL_SRDTEXT

View file

@ -1,19 +0,0 @@
/******************************************************************************/
/* VERSION NUMBERS ************************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_VERSION
#define _H_LW_LIB_VERSION
#include <lw/lib/Externals.hh>
namespace lw {
static constexpr inline uint32_t LibVersion( )
{ return 0; }
static constexpr inline uint32_t LibRevision( )
{ return 0; }
}
#endif // _H_LW_LIB_VERSION

View file

@ -1,19 +0,0 @@
/******************************************************************************/
/* VERSION NUMBERS ************************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_VERSION
#define _H_LW_LIB_VERSION
#include <lw/lib/Externals.hh>
namespace lw {
static constexpr inline uint32_t LibVersion( )
{ return __VERSION__; }
static constexpr inline uint32_t LibRevision( )
{ return __REVISION__; }
}
#endif // _H_LW_LIB_VERSION

View file

@ -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 <lw/lib/DynLib.hh>
namespace lw {
#include <ebcl/DynLib.hh>
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

View file

@ -1,154 +0,0 @@
/******************************************************************************/
/* UI<=>GAME MESSAGES - INLINE CODE *******************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_MESSAGES
#define _H_LW_LIB_INLINE_MESSAGES
#include <lw/lib/GameLoop.hh>
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

View file

@ -1,59 +0,0 @@
/******************************************************************************/
/* MODDING SYSTEM - INLINE CODE ***********************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_MODS
#define _H_LW_LIB_INLINE_MODS
#include <lw/lib/Mods.hh>
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

View file

@ -2,10 +2,10 @@
/* SRD - BINARY STORAGE - INLINE CODE *****************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDBINARY
#define _H_LW_LIB_INLINE_SRDBINARY
#include <lw/lib/SRDBinary.hh>
namespace lw {
#ifndef _H_EBCL_INLINE_SRDBINARY
#define _H_EBCL_INLINE_SRDBINARY
#include <ebcl/SRDBinary.hh>
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

View file

@ -2,10 +2,10 @@
/* SRD - DATA - INLINE CODE ***************************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDDATA
#define _H_LW_LIB_INLINE_SRDDATA
#include <lw/lib/SRDData.hh>
namespace lw {
#ifndef _H_EBCL_INLINE_SRDDATA
#define _H_EBCL_INLINE_SRDDATA
#include <ebcl/SRDData.hh>
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

View file

@ -2,10 +2,10 @@
/* SRD - PARSER DEFINITIONS - INLINE CODE *************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDDEFINITIONS
#define _H_LW_LIB_INLINE_SRDDEFINITIONS
#include <lw/lib/SRDDefinitions.hh>
namespace lw {
#ifndef _H_EBCL_INLINE_SRDDEFINITIONS
#define _H_EBCL_INLINE_SRDDEFINITIONS
#include <ebcl/SRDDefinitions.hh>
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

View file

@ -2,10 +2,10 @@
/* SRD - INPUT AND OUTPUT - INLINE CODE ***************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDIO
#define _H_LW_LIB_INLINE_SRDIO
#include <lw/lib/SRDIO.hh>
namespace lw {
#ifndef _H_EBCL_INLINE_SRDIO
#define _H_EBCL_INLINE_SRDIO
#include <ebcl/SRDIO.hh>
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

View file

@ -2,10 +2,10 @@
/* SRD - PARSER CONFIGURATION - INLINE CODE ***********************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDPARSERCONFIG
#define _H_LW_LIB_INLINE_SRDPARSERCONFIG
#include <lw/lib/SRDParserConfig.hh>
namespace lw {
#ifndef _H_EBCL_INLINE_SRDPARSERCONFIG
#define _H_EBCL_INLINE_SRDPARSERCONFIG
#include <ebcl/SRDParserConfig.hh>
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

View file

@ -2,10 +2,10 @@
/* SRD - TEXT STORAGE - INLINE CODE *******************************************/
/******************************************************************************/
#ifndef _H_LW_LIB_INLINE_SRDTEXT
#define _H_LW_LIB_INLINE_SRDTEXT
#include <lw/lib/SRDText.hh>
namespace lw {
#ifndef _H_EBCL_INLINE_SRDTEXT
#define _H_EBCL_INLINE_SRDTEXT
#include <ebcl/SRDText.hh>
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

View file

@ -1,667 +0,0 @@
/******************************************************************************/
/* CONSOLE SUPPORT - UNIX IMPLEMENTATION **************************************/
/******************************************************************************/
#include <lw/lib/Console.hh>
#include <unistd.h>
#include <termios.h>
#include <pty.h>
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;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,83 +0,0 @@
#include <lw/lib/BuiltinLoggers.hh>
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 ) );
}

View file

@ -1,153 +0,0 @@
/******************************************************************************/
/* LOGGING SYSTEM - BUILT-IN LOGGERS - NON-VFS FILE LOG WRITER ****************/
/******************************************************************************/
#include <lw/lib/BuiltinLoggers.hh>
#include <lw/lib/SRDParser.hh>
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;
}
}

View file

@ -2,9 +2,9 @@
/* DYNAMIC LIBRARIES **********************************************************/
/******************************************************************************/
#include <lw/lib/DynLib.hh>
#include <lw/lib/Threading.hh>
using namespace lw;
#include <ebcl/DynLib.hh>
#include <ebcl/Threading.hh>
using namespace ebcl;
#ifdef _WIN32
# error "Not implemented"

View file

@ -1,140 +0,0 @@
/******************************************************************************/
/* GAME'S MAIN LOOP ***********************************************************/
/******************************************************************************/
#include <lw/lib/GameLoop.hh>
#include <lw/lib/Threading.hh>
#include <lw/lib/Log.hh>
#include <lw/lib/LW.hh>
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( );
}

603
src/LW.cc
View file

@ -1,603 +0,0 @@
/******************************************************************************/
/* MAIN CLASS *****************************************************************/
/******************************************************************************/
#include <lw/lib/LW.hh>
#include <lw/lib/BuiltinLoggers.hh>
#include <lw/lib/SRDBinary.hh>
#include <lw/lib/SRDParser.hh>
#include <lw/lib/SRDText.hh>
#include <lw/lib/MemoryStreams.hh>
#include <lw/lib/VFSDrivers.hh>
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 ) );
}

1041
src/Log.cc

File diff suppressed because it is too large Load diff

View file

@ -1,86 +0,0 @@
/******************************************************************************/
/* UI<=>GAME MESSAGES *********************************************************/
/******************************************************************************/
#include <lw/lib/Messages.hh>
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

View file

@ -1,20 +0,0 @@
/******************************************************************************/
/* MODDING SYSTEM INTERFACES **************************************************/
/******************************************************************************/
#include <lw/lib/ModInterface.hh>
using namespace lw;
/*= A_ModBase ===============================================================*/
A_ModBase::~A_ModBase( ) noexcept
{ }
/*= A_NativeMod ==============================================================*/
OP_UserInterface A_NativeMod::getUserInterface( ) const noexcept
{
return {};
}

File diff suppressed because it is too large Load diff

View file

@ -2,8 +2,8 @@
/* SRD PARSER AND PREPROCESSOR - BINARY FORM **********************************/
/******************************************************************************/
#include <lw/lib/SRDBinary.hh>
using namespace lw;
#include <ebcl/SRDBinary.hh>
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< >

View file

@ -2,10 +2,9 @@
/* SRD PARSER AND PREPROCESSOR - DATA REPRESENTATION **************************/
/******************************************************************************/
#include <lw/lib/SRDData.hh>
#include <lw/lib/Alloc.hh>
#include <lw/lib/Log.hh>
using namespace lw;
#include <ebcl/SRDData.hh>
#include <ebcl/Alloc.hh>
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_ );

View file

@ -3,8 +3,8 @@
/******************************************************************************/
#include <lw/lib/SRDDefinitions.hh>
using namespace lw;
#include <ebcl/SRDDefinitions.hh>
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 << '(';

View file

@ -3,8 +3,8 @@
/******************************************************************************/
#include <lw/lib/SRDIO.hh>
using namespace lw;
#include <ebcl/SRDIO.hh>
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( );

File diff suppressed because it is too large Load diff

View file

@ -3,8 +3,8 @@
/******************************************************************************/
#include <lw/lib/SRDParser.hh>
using namespace lw;
#include <ebcl/SRDParser.hh>
using namespace ebcl;
/*= T_SRDParserData ==========================================================*/

View file

@ -2,8 +2,8 @@
/* SRD - PARSER CONFIGURATION *************************************************/
/******************************************************************************/
#include <lw/lib/SRDParserConfig.hh>
using namespace lw;
#include <ebcl/SRDParserConfig.hh>
using namespace ebcl;
namespace {

File diff suppressed because it is too large Load diff

View file

@ -3,8 +3,8 @@
/******************************************************************************/
#include <lw/lib/SRDText.hh>
using namespace lw;
#include <ebcl/SRDText.hh>
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;

View file

@ -5,6 +5,8 @@
#include <ebcl/Utilities.hh>
#include <ebcl/Arrays.hh>
#include <ebcl/Strings.hh>
#include <ebcl/SRDData.hh>
#include <ebcl/SRDDefinitions.hh>
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 >;
/*----------------------------------------------------------------------------*/

View file

@ -1,159 +0,0 @@
/******************************************************************************/
/* LOGGING SYSTEM - BUILT-IN LOGGERS - TEXT FILE LOGGER ***********************/
/******************************************************************************/
#include <lw/lib/BuiltinLoggers.hh>
#include <lw/lib/SRDParser.hh>
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;
}
}

View file

@ -1,930 +0,0 @@
/******************************************************************************/
/* VIRTUAL FILE SYSTEM ********************************************************/
/******************************************************************************/
#include <lw/lib/VFS.hh>
#ifndef _WIN32
# include <sys/stat.h>
# include <dirent.h>
# include <unistd.h>
#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 );
}

View file

@ -1,614 +0,0 @@
/******************************************************************************/
/* VIRTUAL FILE SYSTEM - NON-ESSENTIAL DRIVERS ********************************/
/******************************************************************************/
#include <lw/lib/VFSDrivers.hh>
#include <lw/lib/Threading.hh>
#include <lw/lib/MemoryStreams.hh>
#include <lw/lib/BinaryStreams.hh>
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 ) );
}

View file

@ -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

View file

@ -1,7 +1,7 @@
#include <lw/lib/Alloc.hh>
#include <lw/lib/Pointers.hh>
#include <ebcl/Alloc.hh>
#include <ebcl/Pointers.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class AllocPoolTest : public CppUnit::TestFixture

View file

@ -1,468 +0,0 @@
#include <lw/lib/Console.hh>
#include <cppunit/extensions/HelperMacros.h>
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 );
}

View file

@ -1,405 +0,0 @@
#include <lw/lib/Console.hh>
#include <cppunit/extensions/HelperMacros.h>
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 );
}
}

View file

@ -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

View file

@ -1,649 +0,0 @@
#include <lw/lib/Log.hh>
#include <cppunit/extensions/HelperMacros.h>
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 );
}

View file

@ -1,6 +1,6 @@
#include <lw/lib/Threading.hh>
#include <ebcl/Threading.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class RingBufferTest : public CppUnit::TestFixture

View file

@ -2,7 +2,7 @@
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TextTestRunner.h>
int main( int argc , char * argv[] )
int main( int , char *[] )
{
CppUnit::TextTestRunner runner;
runner.addTest( CppUnit::TestFactoryRegistry::getRegistry( )

View file

@ -1,7 +1,7 @@
#include <lw/lib/SRDBinary.hh>
#include <lw/lib/MemoryStreams.hh>
#include <ebcl/SRDBinary.hh>
#include <ebcl/MemoryStreams.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
#define V1PROLOGUE_ \

View file

@ -1,7 +1,7 @@
#include <lw/lib/SRDBinary.hh>
#include <lw/lib/MemoryStreams.hh>
#include <ebcl/SRDBinary.hh>
#include <ebcl/MemoryStreams.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class SRDBinWriterTest : public CppUnit::TestFixture

View file

@ -1,6 +1,6 @@
#include <lw/lib/SRDText.hh>
#include <ebcl/SRDText.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class SRDLexerTest : public CppUnit::TestFixture

View file

@ -1,6 +1,6 @@
#include <lw/lib/SRDIO.hh>
#include <ebcl/SRDIO.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
/* - SRDMemTargetTest ---------------------------------------------------{{{-*/
class SRDMemTargetTest : public CppUnit::TestFixture

View file

@ -1,6 +1,6 @@
#include <lw/lib/SRDParserConfig.hh>
#include <ebcl/SRDParserConfig.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class SRDParserConfigTest : public CppUnit::TestFixture

View file

@ -1,6 +1,6 @@
#include <lw/lib/SRDDefinitions.hh>
#include <ebcl/SRDDefinitions.hh>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class SRDInputItemTest : public CppUnit::TestFixture

View file

@ -1,7 +1,7 @@
#include <lw/lib/SRDParser.hh>
#include <lw/lib/SRDText.hh>
#include <ebcl/SRDParser.hh>
#include <ebcl/SRDText.hh>
#include <cppunit/extensions/HelperMacros.h>
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( ) ); } ,

View file

@ -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 ) );
}

File diff suppressed because it is too large Load diff

View file

@ -1,108 +0,0 @@
#ifndef TESTS_SRDPREPROCCMDCOMMON_H_
#define TESTS_SRDPREPROCCMDCOMMON_H_
#include <lw/lib/SRDPreproc.hh>
#include <lw/lib/SRDText.hh>
#include <lw/lib/SRDIO.hh>
#include <lw/lib/MemoryStreams.hh>
#include <cppunit/extensions/HelperMacros.h>
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_

View file

@ -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 ) );
}

File diff suppressed because it is too large Load diff

View file

@ -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 ) );
}

View file

@ -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 );
}

View file

@ -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 ) );
}

View file

@ -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 ) );
}

View file

@ -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 ) );
}

View file

@ -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 ) );
}

View file

@ -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 ) );
}

View file

@ -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 ) );
}

View file

@ -1,245 +0,0 @@
#include <lw/lib/SRDPreproc.hh>
#include <lw/lib/SRDText.hh>
#include <lw/lib/SRDIO.hh>
#include <cppunit/extensions/HelperMacros.h>
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 ) );
}

View file

@ -1,133 +0,0 @@
#ifndef TESTS_SRDPREPROCLOCATION_H_
#define TESTS_SRDPREPROCLOCATION_H_
#include <lw/lib/SRDPreproc.hh>
#include <lw/lib/SRDText.hh>
#include <lw/lib/SRDIO.hh>
#include <lw/lib/MemoryStreams.hh>
#include <cppunit/extensions/HelperMacros.h>
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_

View file

@ -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 );
}

View file

@ -1,8 +1,8 @@
#include <lw/lib/SRDText.hh>
#include <lw/lib/MemoryStreams.hh>
#include <ebcl/SRDText.hh>
#include <ebcl/MemoryStreams.hh>
#include <cmath>
#include <cppunit/extensions/HelperMacros.h>
using namespace lw;
using namespace ebcl;
class SRDTextWriterTest : public CppUnit::TestFixture

View file

@ -1,268 +0,0 @@
#include <lw/lib/Files.hh>
#include <cppunit/extensions/HelperMacros.h>
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

View file

@ -1,318 +0,0 @@
#include <lw/lib/VFS.hh>
#include <cppunit/extensions/HelperMacros.h>
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 ] ) );
}
}