From a41f7c099843d23286857f976ab962b336e679c5 Mon Sep 17 00:00:00 2001 From: Myk Taylor Date: Sun, 9 Aug 2020 08:54:42 -0700 Subject: [PATCH] convert XlsxReader module to xlsxreader plugin --- CMakeLists.txt | 12 -- depends/CMakeLists.txt | 2 + library/CMakeLists.txt | 4 +- library/LuaApi.cpp | 61 ---------- library/include/modules/XlsxReader.h | 45 ------- library/modules/XlsxReader.cpp | 115 ----------------- plugins/CMakeLists.txt | 11 ++ plugins/lua/xlsxreader.lua | 17 +++ plugins/xlsxreader.cpp | 176 +++++++++++++++++++++++++++ 9 files changed, 207 insertions(+), 236 deletions(-) delete mode 100644 library/include/modules/XlsxReader.h delete mode 100644 library/modules/XlsxReader.cpp create mode 100644 plugins/lua/xlsxreader.lua create mode 100644 plugins/xlsxreader.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb8c8d12..cd06587eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -364,8 +364,6 @@ endif() #### expose depends #### -include(ExternalProject) - if(UNIX) # Rescan for pthread and zlib if the build arch changed if(NOT "${DFHACK_BUILD_ARCH}" STREQUAL "${DFHACK_BUILD_ARCH_PREV}") @@ -417,18 +415,8 @@ endif() # build the lib itself if(BUILD_LIBRARY) - include_directories(${XLSXIO_INSTALL_DIR}/include) - add_library(xlsxio_read STATIC IMPORTED) - set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) - add_library(zip STATIC IMPORTED) - set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) - add_library(expat STATIC IMPORTED) - set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) - add_subdirectory(library) install(FILES LICENSE.rst docs/changelog.txt DESTINATION ${DFHACK_USERDOC_DESTINATION}) - - add_dependencies(dfhack xlsxio_project) endif() file(WRITE "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" ${DFHACK_SETARCH}) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index bb5dc72dc..69ce40ae3 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -32,6 +32,8 @@ foreach(var ${vars}) endif() endforeach() +include(ExternalProject) + if(WIN32) set(EXPAT_LIB_SUFFIX "MD.lib") set(LIB_SUFFIX ".lib") diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 583c8768f..2de293e15 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -144,7 +144,6 @@ set(MODULE_HEADERS include/modules/Translation.h include/modules/Units.h include/modules/World.h - include/modules/XlsxReader.h ) set(MODULE_SOURCES @@ -173,7 +172,6 @@ set(MODULE_SOURCES modules/Units.cpp modules/Windows.cpp modules/World.cpp - modules/XlsxReader.cpp ) set(STATIC_FIELDS_FILES) @@ -411,7 +409,7 @@ if(APPLE) set_target_properties(dfhack PROPERTIES SOVERSION 1.0.0) endif() -target_link_libraries(dfhack protobuf-lite clsocket lua jsoncpp_lib_static xlsxio_read zip expat dfhack-version ${PROJECT_LIBS}) +target_link_libraries(dfhack protobuf-lite clsocket lua jsoncpp_lib_static dfhack-version ${PROJECT_LIBS}) set_target_properties(dfhack PROPERTIES INTERFACE_LINK_LIBRARIES "") target_link_libraries(dfhack-client protobuf-lite clsocket jsoncpp_lib_static) diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 0265eee20..78364083f 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -60,7 +60,6 @@ distribution. #include "modules/Translation.h" #include "modules/Units.h" #include "modules/World.h" -#include "modules/XlsxReader.h" #include "LuaWrapper.h" #include "LuaTools.h" @@ -2481,65 +2480,6 @@ static const LuaWrapper::FunctionReg dfhack_kitchen_module[] = { {NULL, NULL} }; -/***** XlsxReader module *****/ - -static const LuaWrapper::FunctionReg dfhack_xlsxreader_module[] = { - WRAPM(XlsxReader, open_xlsx_file), - WRAPM(XlsxReader, close_xlsx_file), - WRAPM(XlsxReader, open_sheet), - WRAPM(XlsxReader, close_sheet), - {NULL, NULL} -}; - -// internal function to factor out handle extraction -static void * get_xlsxreader_handle(lua_State *L) -{ - if (lua_gettop(L) < 1 || lua_isnil(L, 1)) - { - luaL_error(L, "invalid xlsxreader handle"); - } - luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); - return lua_touserdata(L, 1); -} - -// takes a file handle and returns a table-list of sheet names -static int xlsxreader_list_sheets(lua_State *L) -{ - XlsxReader::xlsx_file_handle file_handle = get_xlsxreader_handle(L); - Lua::PushVector(L, XlsxReader::list_sheets(file_handle), true); - return 1; -} - -// takes the sheet handle and returns a table-list of strings, or nil if we -// already processed the last row in the file. -static int xlsxreader_get_row(lua_State *L) -{ - XlsxReader::xlsx_sheet_handle sheet_handle = get_xlsxreader_handle(L); - bool ok = XlsxReader::get_next_row(sheet_handle); - if (!ok) - { - lua_pushnil(L); - } - else - { - std::string value; - auto cells = std::vector(); - while (XlsxReader::get_next_cell(sheet_handle, value)) - { - cells.push_back(value); - } - Lua::PushVector(L, cells, true); - } - - return 1; -} - -static const luaL_Reg dfhack_xlsxreader_funcs[] = { - {"list_sheets", xlsxreader_list_sheets}, - {"get_row", xlsxreader_get_row}, - {NULL, NULL} -}; - /***** Console module *****/ namespace console { @@ -3093,7 +3033,6 @@ void OpenDFHackApi(lua_State *state) OpenModule(state, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs); OpenModule(state, "designations", dfhack_designations_module, dfhack_designations_funcs); OpenModule(state, "kitchen", dfhack_kitchen_module); - OpenModule(state, "xlsxreader", dfhack_xlsxreader_module, dfhack_xlsxreader_funcs); OpenModule(state, "console", dfhack_console_module); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); } diff --git a/library/include/modules/XlsxReader.h b/library/include/modules/XlsxReader.h deleted file mode 100644 index 93ea1cf20..000000000 --- a/library/include/modules/XlsxReader.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Wrapper for xlsxio_read library functions. - */ - -#pragma once - -#include -#include - -#include "Export.h" - -/** - * \defgroup grp_xlsx_reader Xlsx file reader - * @ingroup grp_modules - */ -namespace DFHack -{ -namespace XlsxReader -{ - -typedef void* xlsx_file_handle; -typedef void* xlsx_sheet_handle; - -// returns NULL on error -DFHACK_EXPORT xlsx_file_handle open_xlsx_file(std::string filename); -DFHACK_EXPORT void close_xlsx_file(xlsx_file_handle file_handle); -DFHACK_EXPORT std::vector list_sheets(xlsx_file_handle file_handle); - -// returns XLSXIOReaderSheet object or NULL on error -DFHACK_EXPORT xlsx_sheet_handle open_sheet( - xlsx_file_handle file_handle, std::string sheet_name); -DFHACK_EXPORT void close_sheet(xlsx_sheet_handle sheet_handle); - -// start reading the next row of data; must be called before GetNextCell . -// returns false if there is no next row to get. -DFHACK_EXPORT bool get_next_row(xlsx_sheet_handle sheet_handle); - -// fills the value param with the contents of the cell in the next column cell -// in the current row. -// returns false if there are no more cells in this row. -DFHACK_EXPORT bool get_next_cell( - xlsx_sheet_handle sheet_handle, std::string& value); - -} -} diff --git a/library/modules/XlsxReader.cpp b/library/modules/XlsxReader.cpp deleted file mode 100644 index 405369c85..000000000 --- a/library/modules/XlsxReader.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Wrapper for xlsxio_read library functions. - * - * Sample usage: - * - * std::string filename = "sample_file.xlsx"; - * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); - * if (xlsxfile == NULL) { - * printf("cannot open file: '%s'", filename.c_str()); - * return false; - * } - * auto sheetNames = XlsxReader::list_sheets(xlsxfile); - * for (auto sheetName = sheetNames.begin(); - * sheetName != sheetNames.end(); - * ++sheetName) { - * printf("reading sheet: %s\n", sheetName->c_str()); - * xlsxioreadersheet xlsxsheet = - * XlsxReader::open_sheet(xlsxfile, *sheetName); - * if (xlsxsheet == NULL) { - * printf("cannot open sheet: '%s'", sheetName->c_str()); - * continue; - * } - * std::string value; - * int row_num = 1; - * while (XlsxReader::GetNextRow(xlsxsheet)) { - * std::string s; - * printf("%d:\t", row_num); - * while (XlsxReader::GetNextCell(xlsxsheet, s)) { - * printf("%s\t", s.c_str()); - * } - * printf("\n"); - * ++row_num; - * } - * XlsxReader::close_sheet(xlsxsheet); - * } - * XlsxReader::close_xlsx_file(xlsxfile); - * return true; - */ - -#include - -#include "modules/XlsxReader.h" - -using namespace DFHack; - - -// returns NULL on error -DFHACK_EXPORT XlsxReader::xlsx_file_handle XlsxReader::open_xlsx_file( - std::string filename) -{ - return xlsxioread_open(filename.c_str()); -} - -DFHACK_EXPORT void XlsxReader::close_xlsx_file( - XlsxReader::xlsx_file_handle file_handle) -{ - xlsxioread_close((xlsxioreader)file_handle); -} - -static int list_callback(const XLSXIOCHAR* name, void* cbdata) -{ - auto sheetNames = (std::vector *)cbdata; - sheetNames->push_back(name); - return 0; -} - -DFHACK_EXPORT std::vector XlsxReader::list_sheets( - XlsxReader::xlsx_file_handle file_handle) -{ - auto sheetNames = std::vector(); - xlsxioread_list_sheets( - (xlsxioreader)file_handle, list_callback, &sheetNames); - return sheetNames; -} - -// returns XLSXIOReaderSheet object or NULL on error -DFHACK_EXPORT XlsxReader::xlsx_sheet_handle XlsxReader::open_sheet( - XlsxReader::xlsx_file_handle file_handle, std::string sheet_name) -{ - if (file_handle == NULL) - return NULL; - return xlsxioread_sheet_open( - (xlsxioreader)file_handle, sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); -} - -DFHACK_EXPORT void XlsxReader::close_sheet( - XlsxReader::xlsx_sheet_handle sheet_handle) -{ - xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); -} - -// start reading the next row of data; must be called before GetNextCell . -// returns false if there is no next row to get. -DFHACK_EXPORT bool XlsxReader::get_next_row( - XlsxReader::xlsx_sheet_handle sheet_handle) -{ - return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; -} - -// fills the value param with the contents of the cell in the next column cell -// in the current row. -// returns false if there are no more cells in this row. -DFHACK_EXPORT bool XlsxReader::get_next_cell( - XlsxReader::xlsx_sheet_handle sheet_handle, std::string& value) -{ - char* result; - if (!xlsxioread_sheet_next_cell_string((xlsxioreadersheet)sheet_handle, - &result)) { - value.clear(); - return false; - } - value.assign(result); - free(result); - return true; -} diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 678b7eec2..6531165e1 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -77,6 +77,14 @@ set_source_files_properties( Brushes.h PROPERTIES HEADER_FILE_ONLY TRUE ) add_library(buildingplan-lib STATIC buildingplan-lib.cpp) target_link_libraries(buildingplan-lib dfhack) +# xlsxreader deps +add_library(xlsxio_read STATIC IMPORTED) +set_target_properties(xlsxio_read PROPERTIES IMPORTED_LOCATION ${XLSXIO_LIB}) +add_library(zip STATIC IMPORTED) +set_target_properties(zip PROPERTIES IMPORTED_LOCATION ${LIBZIP_LIB}) +add_library(expat STATIC IMPORTED) +set_target_properties(expat PROPERTIES IMPORTED_LOCATION ${LIBEXPAT_LIB}) + # Plugins option(BUILD_SUPPORTED "Build the supported plugins (reveal, probe, etc.)." ON) if(BUILD_SUPPORTED) @@ -175,8 +183,11 @@ if(BUILD_SUPPORTED) add_subdirectory(tweak) dfhack_plugin(workflow workflow.cpp LINK_LIBRARIES lua) dfhack_plugin(workNow workNow.cpp) + dfhack_plugin(xlsxreader xlsxreader.cpp LINK_LIBRARIES lua xlsxio_read zip expat z) dfhack_plugin(zone zone.cpp LINK_LIBRARIES lua) endif() +target_include_directories(xlsxreader PRIVATE ${XLSXIO_INSTALL_DIR}/include) +add_dependencies(xlsxreader xlsxio_project) # this is the skeleton plugin. If you want to make your own, make a copy and then change it option(BUILD_SKELETON "Build the skeleton plugin." OFF) diff --git a/plugins/lua/xlsxreader.lua b/plugins/lua/xlsxreader.lua new file mode 100644 index 000000000..3dbc1f2d8 --- /dev/null +++ b/plugins/lua/xlsxreader.lua @@ -0,0 +1,17 @@ +local _ENV = mkmodule('plugins.xlsxreader') + +--[[ + + Native functions: + + * file_handle open_xlsx_file(filename) + * close_xlsx_file(file_handle) + * sheet_names list_sheets(file_handle) + + * sheet_handle open_sheet(file_handle, sheet_name) + * close_sheet(sheet_handle) + * cell_strings get_row(sheet_handle) + +--]] + +return _ENV diff --git a/plugins/xlsxreader.cpp b/plugins/xlsxreader.cpp new file mode 100644 index 000000000..9c773718d --- /dev/null +++ b/plugins/xlsxreader.cpp @@ -0,0 +1,176 @@ +/* + * Wrapper for xlsxio_read library functions. + * + * Sample usage: + * + * std::string filename = "sample_file.xlsx"; + * xlsxioreader xlsxfile = XlsxReader::open_xlsx_file(filename); + * if (xlsxfile == NULL) { + * printf("cannot open file: '%s'", filename.c_str()); + * return false; + * } + * auto sheetNames = XlsxReader::list_sheets(xlsxfile); + * for (auto sheetName = sheetNames.begin(); + * sheetName != sheetNames.end(); + * ++sheetName) { + * printf("reading sheet: %s\n", sheetName->c_str()); + * xlsxioreadersheet xlsxsheet = + * XlsxReader::open_sheet(xlsxfile, *sheetName); + * if (xlsxsheet == NULL) { + * printf("cannot open sheet: '%s'", sheetName->c_str()); + * continue; + * } + * std::string value; + * int row_num = 1; + * while (XlsxReader::GetNextRow(xlsxsheet)) { + * std::string s; + * printf("%d:\t", row_num); + * while (XlsxReader::GetNextCell(xlsxsheet, s)) { + * printf("%s\t", s.c_str()); + * } + * printf("\n"); + * ++row_num; + * } + * XlsxReader::close_sheet(xlsxsheet); + * } + * XlsxReader::close_xlsx_file(xlsxfile); + * return true; + */ + +#include + +#include "DataFuncs.h" +#include "LuaTools.h" +#include "PluginManager.h" + +using namespace DFHack; + +DFHACK_PLUGIN("xlsxreader"); + +typedef void* xlsx_file_handle; +typedef void* xlsx_sheet_handle; + +// returns NULL on error +xlsx_file_handle open_xlsx_file(std::string filename) +{ + return xlsxioread_open(filename.c_str()); +} + +void close_xlsx_file(xlsx_file_handle file_handle) +{ + xlsxioread_close((xlsxioreader)file_handle); +} + +// returns XLSXIOReaderSheet object or NULL on error +xlsx_sheet_handle open_sheet(xlsx_file_handle file_handle, std::string sheet_name) +{ + if (file_handle == NULL) + return NULL; + return xlsxioread_sheet_open((xlsxioreader)file_handle, + sheet_name.c_str(), XLSXIOREAD_SKIP_NONE); +} + +void close_sheet(xlsx_sheet_handle sheet_handle) +{ + xlsxioread_sheet_close((xlsxioreadersheet)sheet_handle); +} + +static int list_callback(const XLSXIOCHAR* name, void* cbdata) +{ + auto sheetNames = (std::vector *)cbdata; + sheetNames->push_back(name); + return 0; +} + +// start reading the next row of data; must be called before get_next_cell. +// returns false if there is no next row to get. +static bool get_next_row(xlsx_sheet_handle sheet_handle) +{ + return xlsxioread_sheet_next_row((xlsxioreadersheet)sheet_handle) != 0; +} + +// fills the value param with the contents of the cell in the next column cell +// in the current row. +// returns false if there are no more cells in this row. +static bool get_next_cell(xlsx_sheet_handle sheet_handle, std::string& value) +{ + char* result; + if (!xlsxioread_sheet_next_cell_string( + (xlsxioreadersheet)sheet_handle, &result)) { + value.clear(); + return false; + } + value.assign(result); + free(result); + return true; +} + +// internal function to factor out handle extraction +static void * get_xlsxreader_handle(lua_State *L) +{ + if (lua_gettop(L) < 1 || lua_isnil(L, 1)) + { + luaL_error(L, "invalid xlsxreader handle"); + } + luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); + return lua_touserdata(L, 1); +} + +// takes a file handle and returns a table-list of sheet names +int list_sheets(lua_State *L) +{ + xlsxioreader file_handle = (xlsxioreader)get_xlsxreader_handle(L); + auto sheetNames = std::vector(); + xlsxioread_list_sheets(file_handle, list_callback, &sheetNames); + Lua::PushVector(L, sheetNames, true); + return 1; +} + +// takes the sheet handle and returns a table-list of strings, or nil if we +// already processed the last row in the file. +int get_row(lua_State *L) +{ + xlsxioreadersheet sheet_handle = + (xlsxioreadersheet)get_xlsxreader_handle(L); + bool ok = get_next_row(sheet_handle); + if (!ok) + { + lua_pushnil(L); + } + else + { + std::string value; + auto cells = std::vector(); + while (get_next_cell(sheet_handle, value)) + { + cells.push_back(value); + } + Lua::PushVector(L, cells, true); + } + + return 1; +} + +DFHACK_PLUGIN_LUA_FUNCTIONS { + DFHACK_LUA_FUNCTION(open_xlsx_file), + DFHACK_LUA_FUNCTION(close_xlsx_file), + DFHACK_LUA_FUNCTION(open_sheet), + DFHACK_LUA_FUNCTION(close_sheet), + DFHACK_LUA_END +}; + +DFHACK_PLUGIN_LUA_COMMANDS{ + DFHACK_LUA_COMMAND(list_sheets), + DFHACK_LUA_COMMAND(get_row), + DFHACK_LUA_END +}; + +DFhackCExport command_result plugin_init(color_ostream &, std::vector &) +{ + return CR_OK; +} + +DFhackCExport command_result plugin_shutdown(color_ostream &) +{ + return CR_OK; +}