convert XlsxReader module to xlsxreader plugin

develop
Myk Taylor 2020-08-09 08:54:42 -07:00
parent 5fc627a16f
commit a41f7c0998
9 changed files with 207 additions and 236 deletions

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

@ -32,6 +32,8 @@ foreach(var ${vars})
endif()
endforeach()
include(ExternalProject)
if(WIN32)
set(EXPAT_LIB_SUFFIX "MD.lib")
set(LIB_SUFFIX ".lib")

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

@ -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<std::string>();
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);
}

@ -1,45 +0,0 @@
/*
* Wrapper for xlsxio_read library functions.
*/
#pragma once
#include <string>
#include <vector>
#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<std::string> 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);
}
}

@ -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 <xlsxio_read.h>
#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<std::string> *)cbdata;
sheetNames->push_back(name);
return 0;
}
DFHACK_EXPORT std::vector<std::string> XlsxReader::list_sheets(
XlsxReader::xlsx_file_handle file_handle)
{
auto sheetNames = std::vector<std::string>();
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;
}

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

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

@ -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 <xlsxio_read.h>
#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<std::string> *)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<std::string>();
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<std::string>();
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<PluginCommand> &)
{
return CR_OK;
}
DFhackCExport command_result plugin_shutdown(color_ostream &)
{
return CR_OK;
}