diff --git a/include/tool/coroutine.h b/include/tool/coroutine.h index 5aedc3ecba..84552b2760 100644 --- a/include/tool/coroutine.h +++ b/include/tool/coroutine.h @@ -26,6 +26,7 @@ #ifndef __COROUTINE_H #define __COROUTINE_H +#include #include #include diff --git a/include/tool/examples/Makefile b/include/tool/examples/Makefile index a605263689..8f08757760 100644 --- a/include/tool/examples/Makefile +++ b/include/tool/examples/Makefile @@ -3,7 +3,4 @@ CXXFLAGS = -I../.. -I../../boost all: delegate_example coroutine_example delegate_example: delegate_example.cpp - g++ -o $@ $^ $(CXXFLAGS) - -coroutine_example: coroutine_example.cpp - g++ -o $@ $^ $(CXXFLAGS) -lboost_context \ No newline at end of file + g++ -o $@ $^ $(CXXFLAGS) \ No newline at end of file diff --git a/include/tool/examples/coroutine_example.cpp b/include/tool/examples/coroutine_example.cpp deleted file mode 100644 index c36de8bbef..0000000000 --- a/include/tool/examples/coroutine_example.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include - -#include - -typedef COROUTINE MyCoroutine; - -class MyClass -{ -public: - int CountTo( int n ) - { - printf( "%s: Coroutine says hi. I will count from 1 to %d and yield each value.\n", - __FUNCTION__, - n ); - - for( int i = 1; i <= n; i++ ) - { - printf( "%s: Yielding %d\n", __FUNCTION__, i ); - cofunc.Yield( i ); - } - } - - void Run() - { - cofunc = MyCoroutine( this, &MyClass::CountTo ); - printf( "%s: Calling coroutine that will count from 1 to 5.\n", __FUNCTION__ ); - cofunc.Call( 5 ); - - while( cofunc.Running() ) - { - printf( "%s: Got value: %d\n", __FUNCTION__, cofunc.ReturnValue() ); - cofunc.Resume(); - } - - printf( "%s: Done!\n", __FUNCTION__ ); - } - - MyCoroutine cofunc; -}; - - -main() { - MyClass obj; - - obj.Run(); - - return 0; -} diff --git a/qa/CMakeLists.txt b/qa/CMakeLists.txt index f44721628f..1c774d8385 100644 --- a/qa/CMakeLists.txt +++ b/qa/CMakeLists.txt @@ -22,7 +22,8 @@ add_subdirectory( pcbnew ) add_subdirectory( eeschema ) add_subdirectory( shape_poly_set_refactor ) -# Utility/test programs +# Utility/debugging/profiling programs +add_subdirectory( common_tools ) add_subdirectory( pcb_parse_input ) # add_subdirectory( pcb_test_window ) diff --git a/qa/common_tools/CMakeLists.txt b/qa/common_tools/CMakeLists.txt new file mode 100644 index 0000000000..6c033b02ac --- /dev/null +++ b/qa/common_tools/CMakeLists.txt @@ -0,0 +1,59 @@ +# This program source code file is part of KiCad, a free EDA CAD application. +# +# Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, you may find one here: +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html +# or you may search the http://www.gnu.org website for the version 2 license, +# or you may write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED ) + +add_executable( qa_common_tools + + # # stuff from common due to...units? + # ../../common/eda_text.cpp + + # stuff from common which is needed...why? + ../../common/colors.cpp + ../../common/observable.cpp + + # The main entry point + main.cpp + + tools/coroutines/coroutines.cpp +) + +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/polygon + ${INC_AFTER} +) + +target_link_libraries( qa_common_tools + common + legacy_gal + polygon + bitmaps + gal + qa_utils + ${wxWidgets_LIBRARIES} +) + +# we need to pretend to be something to appease the units code +target_compile_definitions( qa_common_tools + PRIVATE PCBNEW +) \ No newline at end of file diff --git a/qa/common_tools/main.cpp b/qa/common_tools/main.cpp new file mode 100644 index 0000000000..64ca80eec5 --- /dev/null +++ b/qa/common_tools/main.cpp @@ -0,0 +1,123 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#include "tools/coroutines/coroutine_tools.h" + +#include + +/** + * List of registered tools. + * + * This is a pretty rudimentary way to register, but for a simple purpose, + * it's effective enough. When you have a new tool, add it to this list. + */ +const static std::vector known_tools = { + &coroutine_tool, +}; + + +/** + * Print the names and descriptions of the registered tools + */ +static void show_tool_list() +{ + for( const auto& tool : known_tools ) + { + std::cout << tool->m_name << ": \t" << tool->m_desc << std::endl; + } +} + + +/** + * Get the utility program that matches a tool name + * @param aName the name to look for + * @return the tool function + */ +UTILITY_PROGRAM::FUNC* get_program( const std::string& aName ) +{ + for( const auto& tool : known_tools ) + { + if( tool->m_name == aName ) + return &tool->m_func; + } + + return nullptr; +} + + +void print_usage( char* name ) +{ + std::cout << "Run a utility tool." << std::endl; + + std::cout << "Usage: " << name << " [-h] [-l] [TOOL [TOOL_OPTIONS]]" << std::endl; + + std::cout << " -h show this message and exit." << std::endl + << " -l print known tools and exit." << std::endl; + + std::cout << std::endl; + std::cout << "Known tools: " << std::endl; + + show_tool_list(); +} + + +int main( int argc, char** argv ) +{ + wxMessageOutput::Set( new wxMessageOutputStderr ); + + // Need at least one parameter + if( argc < 2 ) + { + print_usage( argv[0] ); + return RET_CODES::BAD_CMDLINE; + } + + const std::string arg1( argv[1] ); + + if( argc == 2 ) + { + if( arg1 == "-h" ) + { + print_usage( argv[0] ); + return RET_CODES::OK; + } + else if( arg1 == "-l" ) + { + show_tool_list(); + return RET_CODES::OK; + } + } + + auto func = get_program( arg1 ); + + if( !func ) + { + std::cout << "Tool " << arg1 << " not found." << std::endl; + return RET_CODES::UNKNOWN_TOOL; + } + + // pass on the rest of the commands + return ( *func )( argc - 1, argv + 1 ); +} \ No newline at end of file diff --git a/qa/common_tools/tools/coroutines/coroutine_tools.h b/qa/common_tools/tools/coroutines/coroutine_tools.h new file mode 100644 index 0000000000..414d0acbf7 --- /dev/null +++ b/qa/common_tools/tools/coroutines/coroutine_tools.h @@ -0,0 +1,10 @@ + +#ifndef COROUTINES_UTILTY_H +#define COROUTINES_UTILTY_H + +#include + +/// A tool to test a simple coroutine +extern UTILITY_PROGRAM coroutine_tool; + +#endif \ No newline at end of file diff --git a/qa/common_tools/tools/coroutines/coroutines.cpp b/qa/common_tools/tools/coroutines/coroutines.cpp new file mode 100644 index 0000000000..28f83045d7 --- /dev/null +++ b/qa/common_tools/tools/coroutines/coroutines.cpp @@ -0,0 +1,131 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "coroutine_tools.h" + +#include +#include + +#include + +#include + +#include + + +typedef COROUTINE MyCoroutine; + +class CoroutineExample +{ +public: + CoroutineExample( int aCount ) : m_count( aCount ) + { + } + + int CountTo( int n ) + { + printf( "%s: Coroutine says hi. I will count from 1 to %d and yield each value.\n", + __FUNCTION__, n ); + + for( int i = 1; i <= n; i++ ) + { + printf( "%s: Yielding %d\n", __FUNCTION__, i ); + m_cofunc->KiYield( i ); + } + + return 0; + } + + void Run() + { + m_cofunc = std::make_unique( this, &CoroutineExample::CountTo ); + printf( "%s: Calling coroutine that will count from 1 to 5.\n", __FUNCTION__ ); + m_cofunc->Call( m_count ); + + while( m_cofunc->Running() ) + { + printf( "%s: Got value: %d\n", __FUNCTION__, m_cofunc->ReturnValue() ); + m_cofunc->Resume(); + } + + printf( "%s: Done!\n", __FUNCTION__ ); + } + + std::unique_ptr m_cofunc; + int m_count; +}; + + +static const wxCmdLineEntryDesc g_cmdLineDesc[] = { + { + wxCMD_LINE_SWITCH, + "h", + "help", + _( "displays help on the command line parameters" ).mb_str(), + wxCMD_LINE_VAL_NONE, + wxCMD_LINE_OPTION_HELP, + }, + { + wxCMD_LINE_OPTION, + "c", + "count", + _( "how high to count" ).mb_str(), + wxCMD_LINE_VAL_NUMBER, + wxCMD_LINE_PARAM_OPTIONAL, + }, + { wxCMD_LINE_NONE } +}; + + +static int coroutine_main_func( int argc, char** argv ) +{ + wxCmdLineParser cl_parser( argc, argv ); + cl_parser.SetDesc( g_cmdLineDesc ); + cl_parser.AddUsageText( _( "Test a simple coroutine that yields a given number of times" ) ); + + int cmd_parsed_ok = cl_parser.Parse(); + if( cmd_parsed_ok != 0 ) + { + // Help and invalid input both stop here + return ( cmd_parsed_ok == -1 ) ? RET_CODES::OK : RET_CODES::BAD_CMDLINE; + } + + long count = 5; + cl_parser.Found( "count", &count ); + + CoroutineExample obj( (int) count ); + + obj.Run(); + + return RET_CODES::OK; +} + + +/* + * Define the tool interface + */ +UTILITY_PROGRAM coroutine_tool = { + "coroutine", + "Test a simple coroutine", + coroutine_main_func, +}; \ No newline at end of file diff --git a/qa/qa_utils/utility_program.h b/qa/qa_utils/utility_program.h new file mode 100644 index 0000000000..e9708f8737 --- /dev/null +++ b/qa/qa_utils/utility_program.h @@ -0,0 +1,77 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef UTILITY_PROGRAM_H +#define UTILITY_PROGRAM_H + +#include + +/** + * Return codes for tools + */ +enum RET_CODES +{ + /// Tool exited OK + OK = 0, + + /// The command line was not correct for the tool + BAD_CMDLINE = 1, + + /// The tool asked for was not found + UNKNOWN_TOOL = 2, + + /// Tools can define their own statuses from here onwards + TOOL_SPECIFIC = 10, +}; + + +/** + * Description of a "utility program", which is a program that + * takes some command line and does "something". + * + * Likely uses of this are: + * + * * Test programs and demos + * * Benchmarks + * * Fuzz targets + * + * This structure allows a single executable to select a program from + * many registered programs to avoid having to maintain "N" similar CMake + * scripts and perform "N" linkages. + */ +struct UTILITY_PROGRAM +{ + /// A function that provides the program for a given command line + using FUNC = std::function; + + /// The name of the program (this is used to select one) + std::string m_name; + + /// Description of the program + std::string m_desc; + + /// The function to call to run the program + FUNC m_func; +}; + +#endif // UTILITY_PROGRAM_H \ No newline at end of file