136 Commits

Author SHA1 Message Date
9e5a5970a3 Improved PIBlockingDeque constructors
- resolve creation from constant (see test construct_from_constant_is_max_size_eq_capacity)
- add tests for constructors
2020-08-11 12:30:28 +03:00
46d93c6c9f Improved PIBlockingDeque behaviour and unit tests for put, offer, take methods
- Methods put, offer, take begins working with move and copy semantics
- Mocking queue condition variables with GMock in Unit tests
- Rewrite part of unit tests
2020-08-07 19:12:09 +03:00
662a2fc464 Refactor PIBlockingDequeue 2020-08-07 10:10:05 +03:00
194389ef6d Refactor templates & submit doc 2020-08-06 13:23:49 +03:00
3cfdda7365 PIThreadPoolExecutor & PIBlockingDequeue improvements
- add support move & copy semantic
- introduce submit method for executor with future result
2020-08-05 22:59:33 +03:00
3ec1ecfb5b refactor concurrent module code 2020-08-04 16:39:08 +03:00
be51728570 Merge remote-tracking branch 'origin/master' into concurrent 2020-08-03 17:48:36 +03:00
41e54e5859 Merge pip2 2020-08-03 17:47:19 +03:00
9cd108cf20 tests binary dir fix 2020-08-03 11:10:27 +03:00
22208fbf51 tests binary dir fix 2020-08-03 11:10:05 +03:00
badaa01deb Merge remote-tracking branch 'origin/master' into concurrent
# Conflicts:
#	lib/main/thread/pithreadpoolexecutor.cpp
#	lib/main/thread/pithreadpoolexecutor.h
#	tests/concurrent/ExecutorIntegrationTest.cpp
#	tests/concurrent/ExecutorUnitTest.cpp
#	tests/concurrent/testutil.h
2020-08-03 10:18:52 +03:00
e8a066abcd doc 2020-08-03 09:04:50 +03:00
427e7411c1 move most old PIMap iterators to new
Documentation of PIVector, PIMap and PIMapIterator
2020-08-03 01:43:23 +03:00
df457a1602 rename "iterate" 2020-08-02 19:18:28 +03:00
1dfcaf4952 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-08-02 15:57:27 +03:00
b468a6d581 PIMapIterator
small PIString optimize
general PIChunkStream pack optimization
2020-08-02 15:57:21 +03:00
b68e8f7a65 Merge picloud branch 2020-08-02 14:00:46 +03:00
1fb5356825 move picompress.h 2020-08-01 23:34:23 +03:00
01f7b15818 remove " " 2020-08-01 23:27:10 +03:00
284971fe8d Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-08-01 23:24:16 +03:00
edacac54f9 PIByteArray rvalue, some fixes 2020-08-01 23:24:08 +03:00
0821742e45 missed exports 2020-08-01 23:18:02 +03:00
2d317a9959 missed exports 2020-08-01 22:42:11 +03:00
7486866c17 CMakeLists.txt fix 2020-08-01 22:34:20 +03:00
c7ac4fa551 Refactored CMakeLists.txt
* new pip_module() macro
 * fixed exports
 * automatic gather all exports and pass them to Doxygen and PICodeParser
2020-08-01 21:29:32 +03:00
21111b3e67 move tests to separate dir
create macro "pip_test()" for easily add new tests
2020-07-31 15:47:08 +03:00
e728b30e5e PIString hard optimization 2020-07-31 14:12:47 +03:00
1d5c979607 fix bug in move constructor 2020-07-31 00:00:26 +03:00
79e17b48b8 rvalue functions for containers 2020-07-30 22:26:05 +03:00
a12e63e569 PIStringList move operator fix 2020-07-30 20:41:38 +03:00
52062e6ccd move operators works 2020-07-30 20:30:24 +03:00
557f2a4d0d replace piForeach* to for(:)
another c++11 try ...
2020-07-30 20:08:33 +03:00
2ffc457566 merged concurrent to main library
removed PIConditionLock, use PIMutex instead
2020-07-30 18:50:42 +03:00
4dd59132d5 LUA lib status, some fixes 2020-07-30 16:17:45 +03:00
48692a4724 remove remote_console 2020-07-30 00:20:19 +03:00
4de3a052f1 time to merge v2 to master 2020-07-29 01:30:46 +03:00
b153673974 CMakeLists.txt 2020-07-27 17:54:07 +03:00
abbbce1380 Merge branch 'pip_2' of https://git.shs.tools/SHS/pip into pip_2 2020-07-25 13:13:58 +03:00
e82831377a CMakeLists.txt 2020-07-25 13:13:53 +03:00
9bd87dcc63 поправил PIP_CONCURRENT_TEST 2020-07-24 14:42:49 +03:00
cdbc401616 fixed FindPIP with Lua 2020-07-24 14:04:19 +03:00
e63aab40f6 fix FindPIP.cmake 2020-07-24 12:14:00 +03:00
422dad847e Merge remote-tracking branch 'remotes/origin/lua' into pip_2 2020-07-23 17:15:36 +03:00
6f58388d8d PILuaProgram 2020-07-22 23:00:31 +03:00
16bbcddf50 PIP Lua Module 2020-07-22 22:20:54 +03:00
b018ea9e07 PIString test for Lua 2020-07-22 21:22:20 +03:00
94c09e1131 test lua support 2020-07-22 21:11:33 +03:00
14f0c192d8 Merge branch 'master' of https://git.shs.tools/SHS/pip into pip_2 2020-07-22 12:15:22 +03:00
20c58f5423 fix cmake for tests 2020-07-20 18:22:55 +03:00
8efd2cf447 Rewrite executor to template & come back executor unit tests 2020-07-17 18:36:28 +03:00
b772928dc1 #15 убрать PIP_CXX11_SUPPORT 2020-07-17 11:51:30 +03:00
33a6382f4d NO_COPY_CLASS c++11 2020-07-17 11:46:21 +03:00
1a3096c48b PIMutex typedef std::mutex, patch PIMutexLocker, replace volatile by atomic 2020-07-17 11:32:04 +03:00
6f5c864e9f PIMutex as std::mutex 2020-07-17 11:14:11 +03:00
ea624a5111 pip_test clear 2020-07-16 13:58:55 +03:00
c642702265 fix main.cpp 2020-07-16 13:44:15 +03:00
478f0a7fd3 arch 32 piswap fixes 2020-07-16 13:41:29 +03:00
1045b274fb fix test main.cpp 2020-07-16 12:52:44 +03:00
5fd429cca6 version 2020-07-16 12:51:34 +03:00
ffd1af904d Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-07-16 12:48:26 +03:00
32f16fdb64 optimize piSwap and c++11 improvments 2020-07-16 12:48:20 +03:00
2f57945c34 Merge pull request 'Added additional poll method without timeout' (#12) from concurrent into master 2020-07-16 12:06:16 +03:00
5df43a45f2 Added additional poll method without timeout 2020-07-16 11:59:47 +03:00
835e6c7773 code clean 2020-07-10 16:57:02 +03:00
614370096c Merge pull request 'Fixed tests and improve multithread sync' (#9) from atomic into master 2020-07-08 15:36:36 +03:00
6cb1040b56 version 2020-07-08 15:27:36 +03:00
6feb628a94 Fixed tests and improve multithread sync 2020-07-07 17:29:59 +03:00
101164902a Merge branch 'master' into picloud 2020-06-28 09:09:59 +03:00
2dfbbf80b7 clean, fix FindPIP.cmake 2020-06-28 01:03:29 +03:00
42925122cb version 1.22.0
source tree changed
detached PIConsole and PIScreen* in "pip_console" library
2020-06-28 00:18:24 +03:00
5de62b1c83 FindPIP patch 2020-06-26 09:51:05 +03:00
d3ffc19610 Merge commit '02ac4020d3f7a948c87dd0349db093934c0aed3c' into picloud 2020-06-18 19:09:21 +03:00
02ac4020d3 api fixes, PIStreamPacker potential fixes 2020-06-18 17:14:33 +03:00
4910631ce8 PIObject::scopeList() fix
DeployMacros supports for "$<>" files
2020-06-17 16:49:02 +03:00
3f7f67e198 picloud start develop 2020-06-15 11:09:34 +03:00
f662a92380 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-06-10 15:36:41 +03:00
5f8f8e0050 remove pifixedpoint.h 2020-06-10 15:36:36 +03:00
99e93dfc62 PIInit 2020-06-10 15:11:22 +03:00
902a40d622 smaaaaal clean 2020-06-10 14:35:52 +03:00
4bd54274c9 clean yet 2020-06-10 14:11:44 +03:00
c59579d5d5 BIG deep clean 2020-06-10 13:14:16 +03:00
f579718e0b version 1.19.0_alpha
general bug fixes and optimization
Merge branch 'master' of https://git.shs.tools/SHS/pip
2020-06-09 18:04:33 +03:00
4ec87e0e2a optimization and fixes 2020-06-09 17:52:17 +03:00
2c6f87839c PIStringList operators 2020-06-09 17:37:06 +03:00
d5cef947ee Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-06-02 13:05:39 +03:00
a01c3144f3 fix math/pimathmatrix.h 2020-06-02 13:05:35 +03:00
2d868d6d68 README.md 2020-05-28 18:20:14 +03:00
86b25303ef Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-05-28 17:08:42 +03:00
67f82558d5 version 1.8.0
PIString: version functions
2020-05-28 17:08:00 +03:00
988ebac3b7 fix PVector2D resize 2020-05-28 14:03:47 +03:00
6b9fa87570 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-05-28 10:16:20 +03:00
6c98600fe7 PIVector2D resize 2020-05-28 10:15:05 +03:00
bfc6d0f18e PISerial::DeviceInfo operators 2020-05-26 18:21:14 +03:00
15515a2954 CMakeLists.txt fix 2020-05-26 16:49:08 +03:00
b6ab5aa202 version 1.16.0_alpha
PISerial::availableDevicesInfo (Linux and Windows)
2020-05-26 16:08:38 +03:00
6413e7747e doc 2020-05-23 21:55:15 +03:00
16bc3891c6 multiline fix 2020-05-23 21:52:16 +03:00
21f8a035d8 PIConfig multiline support 2020-05-23 21:41:47 +03:00
a5809d5f39 - 2020-05-23 17:42:18 +03:00
e04e6199e3 PIGPIO user permission patch 2020-05-22 21:58:05 +03:00
299d1e1708 version 1.15.0_alpha
add PIGPIO class
gcc warnings fix
2020-05-22 21:34:21 +03:00
51a76be487 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-05-22 12:19:56 +03:00
a2898ac737 correct regexp in DeployMacros.cmake 2020-05-22 12:19:50 +03:00
c6be855d0f android patch 2020-05-21 13:07:08 +03:00
f625b87577 DeployMacros LIBS support 2020-05-20 19:49:14 +03:00
ecadc0f2e0 deploy_tool patch for "-a" 2020-05-19 21:08:44 +03:00
1692d389c9 deploy 2020-05-19 18:30:34 +03:00
1899832362 deploy service depends with version 2020-05-19 13:18:09 +03:00
b860d8bbaf deploy 2020-05-18 19:18:15 +03:00
d2cb72c676 debian-service fix 2020-05-18 17:41:45 +03:00
caedece352 debian-service 2020-05-18 16:39:18 +03:00
abe8b76046 version 1.14.0_beta 2020-05-16 11:25:57 +03:00
b212edf090 FindPIP.cmake windows cross-android 2020-05-16 11:11:32 +03:00
2c5e4e9b4c cloud visio 2020-05-15 22:48:58 +03:00
de17f93679 linux deploy 2020-05-12 22:39:16 +03:00
b07fe9f892 linux deploy 2020-05-12 18:48:59 +03:00
e85275c587 dpkg-deb with gzip 2020-05-10 14:36:12 +03:00
25ddc832af deploy features 2020-05-07 17:41:26 +03:00
3386c7702c CROSSTOOLS support 2020-05-04 12:51:01 +03:00
920d13685c deploy for crosslinux 2020-05-03 11:25:37 +03:00
0302048afa AUTHORS 2020-04-30 16:09:57 +03:00
b7c97af69a Licence updated to LGPLv3 2020-04-30 15:59:14 +03:00
2ca1c186a6 Licence updated to LGPLv3 2020-04-30 15:25:31 +03:00
b9eda039a0 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-04-29 18:41:47 +03:00
b24de48931 fix linux piconfig 2020-04-29 18:41:42 +03:00
b9ba2d66b9 DeployMacros.cmake 2020-04-29 18:33:26 +03:00
0ac382e628 config 2020-04-29 17:32:43 +03:00
ad374ea17e config 2020-04-29 17:31:35 +03:00
43588d076f piconfig 2020-04-29 17:26:30 +03:00
3454971100 Merge branch 'master' of https://git.shs.tools/SHS/pip 2020-04-29 17:18:11 +03:00
fda8c61c3f replace PIConfig::Entry operators to functions 2020-04-29 17:17:59 +03:00
7cd698bb72 DeployMacros.cmake 2020-04-29 14:55:17 +03:00
6a6907b136 deploy 2020-04-29 12:58:16 +03:00
ba991ed802 clean 2020-04-28 14:41:07 +03:00
f4cbd499a8 fix README.md 2020-04-27 11:19:47 +03:00
40c3da0389 test 2020-04-26 16:48:00 +03:00
342 changed files with 36030 additions and 38283 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/src_main/piversion.h
/.svn
/doc/rtf
_unsused

View File

@@ -1,2 +1,2 @@
Pelipenko Ivan (peri4) peri4ko@yandex.ru peri4 = Пелипенко Иван <peri4ko@yandex.ru>
Bychkov Andrey (andrey) work.a.b@yandex.ru andrey = Бычков Андрей <andrey@signalmodelling.ru>

View File

@@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0017 NEW) # need include() with .cmake cmake_policy(SET CMP0017 NEW) # need include() with .cmake
project(pip) project(pip)
set(_PIP_MAJOR 1) set(_PIP_MAJOR 1)
set(_PIP_MINOR 13) set(_PIP_MINOR 99)
set(_PIP_REVISION 0) set(_PIP_REVISION 3)
set(_PIP_SUFFIX ) set(_PIP_SUFFIX _prebeta)
set(_PIP_COMPANY SHS) set(_PIP_COMPANY SHS)
set(_PIP_DOMAIN org.SHS) set(_PIP_DOMAIN org.SHS)
@@ -14,11 +14,15 @@ endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
set(PIP_BUILD 1) set(PIP_BUILD 1)
include(CheckFunctionExists) include(CheckFunctionExists)
include(GenerateExportHeader)
include(DeployMacros) include(DeployMacros)
include(PIPMacros) include(PIPMacros)
if(NOT DEFINED BUILD_NUMBER) if(NOT DEFINED BUILD_NUMBER)
set(BUILD_NUMBER 9999) set(BUILD_NUMBER 9999)
endif() endif()
if("x${BUILD_NUMBER}" STREQUAL "x")
set(BUILD_NUMBER 0)
endif()
set(_ICU_DEFAULT OFF) set(_ICU_DEFAULT OFF)
if((NOT DEFINED WIN32) AND (NOT DEFINED ANDROID_PLATFORM) AND (NOT DEFINED APPLE)) if((NOT DEFINED WIN32) AND (NOT DEFINED ANDROID_PLATFORM) AND (NOT DEFINED APPLE))
@@ -37,54 +41,94 @@ set(PIP_UTILS 1)
if(LIBPROJECT) if(LIBPROJECT)
set(PIP_UTILS ${UTILS}) set(PIP_UTILS ${UTILS})
endif() endif()
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
# Apple crosscompiling rpath patch
# macro(apple_rpath_patch _T)
# if (APPLE AND CMAKE_CROSSCOMPILING AND CMAKE_MACOSX_RPATH)
# foreach(_RP ${CMAKE_INSTALL_RPATH})
# add_custom_command(TARGET ${_T} POST_BUILD
# COMMAND "${CMAKE_INSTALL_NAME_TOOL}"
# "-add_rpath" "${_RP}"
# "$<TARGET_FILE_DIR:${_T}>/$<TARGET_FILE_NAME:${_T}>"
# COMMENT "Add to ${_T} rpath \"${_RP}\"")
# endforeach()
# endif()
# endmacro()
# Basic # Basic
macro(gather_src DIR CPP H H_P) set(PIP_MODULES)
set(CS)
set(HS)
set(PHS)
file(GLOB CS "${DIR}/*.cpp")
file(GLOB HS "${DIR}/*.h")
file(GLOB PHS "${DIR}/*_p.h")
list(REMOVE_ITEM HS "${PHS}")
list(APPEND ${CPP} ${CS})
list(APPEND ${H} ${HS})
list(APPEND ${H_P} ${PHS})
endmacro()
set(PIP_SRC_MAIN "src_main")
set(PIP_SRC_CRYPT "src_crypt")
set(PIP_SRC_COMPRESS "src_compress")
set(PIP_SRC_USB "src_usb")
set(PIP_SRC_FFTW "src_fftw")
set(PIP_SRC_OPENCL "src_opencl")
set(PIP_SRC_IO_UTILS "src_io_utils")
set(PIP_SRC_CONCURRENT "src_concurrent")
set(PIP_SRC_CLOUD "src_cloud")
set(PIP_SRC_DIRS "src_main" "src_crypt" "src_compress" "src_usb" "src_fftw" "src_opencl" "src_io_utils" "src_concurrent" "src_cloud")
set(PIP_LIBS_TARGETS pip)
set(LIBS_MAIN) set(LIBS_MAIN)
set(LIBS_STATUS) set(LIBS_STATUS)
set(HDRS)
set(PHDRS)
set(HDR_DIRS)
set(PIP_UTILS_LIST)
set(PIP_TESTS_LIST)
set(PIP_EXPORTS)
if (TESTS) set(PIP_SRC_MODULES "console;crypt;compress;usb;fftw;opencl;io_utils;cloud;lua")
set(PIP_SRC_CONCURRENT_TEST "src_concurrent/test") foreach(_m ${PIP_SRC_MODULES})
endif() set(PIP_MSG_${_m} "no")
endforeach()
macro(pip_module NAME LIBS LABEL INCLUDES MSG)
set(CPPS)
set(HS)
set(PHS)
set(CRES)
file(GLOB_RECURSE CPPS "lib/${NAME}/*.cpp")
file(GLOB_RECURSE HS "lib/${NAME}/*.h")
file(GLOB_RECURSE PHS "lib/${NAME}/*_p.h")
file(GLOB_RECURSE RES "lib/${NAME}/*conf.h")
list(REMOVE_ITEM HS "${PHS}")
list(APPEND HDRS ${HS})
list(APPEND PHDRS ${PHS})
set(_target "pip_${NAME}")
set(_libs "${LIBS}")
if ("${NAME}" STREQUAL "main")
set(_target "pip")
else()
list(APPEND _libs "pip")
endif()
string(TOUPPER "${_target}" DEF_NAME)
set(PIP_MSG_${NAME} "yes${MSG}")
import_version(${_target} PIP)
set_deploy_property(${_target} ${PIP_LIB_TYPE}
LABEL "${LABEL}"
FULLNAME "${_PIP_DOMAIN}.${_target}"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(${_target} _RC)
set(LINK_LIBS)
foreach (_l ${_libs})
if (${${_l}_FOUND})
list(APPEND LINK_LIBS ${${_l}_LIBRARIES})
else()
list(APPEND LINK_LIBS ${_l})
endif()
endforeach()
if (NOT "${RES}" STREQUAL "")
pip_resources(CRES "${RES}")
endif()
add_definitions(-D${DEF_NAME})
add_library(${_target} ${PIP_LIB_TYPE} ${CPPS} ${CRES} ${_RC})
if (NOT "${RES}" STREQUAL "")
add_dependencies(${_target} pip_rc)
endif()
if (NOT "${INCLUDES}" STREQUAL "")
target_include_directories(${_target} PRIVATE ${INCLUDES})
endif()
generate_export_header(${_target})
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/${_target}_export.h")
list(APPEND PIP_EXPORTS "${DEF_NAME}_EXPORT")
target_link_libraries(${_target} ${LINK_LIBS})
list(APPEND PIP_MODULES ${_target})
if (NOT "${LIBS}" STREQUAL "")
list(APPEND LIBS_STATUS ${LIBS})
endif()
endmacro()
macro(pip_find_lib NAME)
find_library(${NAME}_LIBRARIES ${NAME} ${ARGN})
set(${NAME}_FOUND FALSE)
if(${NAME}_LIBRARIES)
set(${NAME}_FOUND TRUE)
endif()
endmacro()
if (DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) if (DEFINED ENV{QNX_HOST} OR PIP_FREERTOS)
set(STATIC_LIB ON) set(STATIC_LIB ON)
@@ -92,11 +136,11 @@ endif()
if(STATIC_LIB) if(STATIC_LIB)
set(PIP_LIB_TYPE STATIC) set(PIP_LIB_TYPE STATIC)
set(PIP_LIB_TYPE_MSG "Static")
add_definitions(-DPIP_STATIC_DEFINE) add_definitions(-DPIP_STATIC_DEFINE)
#message(STATUS "Building PIP static library")
else() else()
set(PIP_LIB_TYPE SHARED) set(PIP_LIB_TYPE SHARED)
#message(STATUS "Building PIP shared library") set(PIP_LIB_TYPE_MSG "Shared")
endif() endif()
@@ -107,14 +151,11 @@ set_version(PIP
REVISION "${_PIP_REVISION}" REVISION "${_PIP_REVISION}"
BUILD "${BUILD_NUMBER}" BUILD "${BUILD_NUMBER}"
SUFFIX "${_PIP_SUFFIX}" SUFFIX "${_PIP_SUFFIX}"
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h") OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/piversion.h")
set_deploy_property(pip ${PIP_LIB_TYPE} if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h")
LABEL "PIP main library" file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h")
FULLNAME "${_PIP_DOMAIN}.pip" endif()
COMPANY "${_PIP_COMPANY}" list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/piversion.h")
INFO "Platform-Independent Primitives")
message(STATUS "Building PIP version ${PIP_VERSION} (${PIP_LIB_TYPE})")
if(MINGW) if(MINGW)
find_package(MinGW REQUIRED) find_package(MinGW REQUIRED)
@@ -130,7 +171,7 @@ else()
set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks;@executable_path/lib;@loader_path/../lib") set(CMAKE_INSTALL_RPATH "@executable_path/../Frameworks;@executable_path/lib;@loader_path/../lib")
set(CMAKE_MACOSX_RPATH 1) set(CMAKE_MACOSX_RPATH 1)
else() else()
set(CMAKE_INSTALL_RPATH "\$ORIGIN/lib") set(CMAKE_INSTALL_RPATH "\$ORIGIN;\$ORIGIN/lib")
endif() endif()
endif() endif()
if(LIB) if(LIB)
@@ -155,59 +196,37 @@ if (NOT DEFINED PIP_CMG)
if (CMAKE_CROSSCOMPILING OR (DEFINED ANDROID_PLATFORM)) if (CMAKE_CROSSCOMPILING OR (DEFINED ANDROID_PLATFORM))
set(PIP_CMG "pip_cmg") set(PIP_CMG "pip_cmg")
set(PIP_RC "pip_rc") set(PIP_RC "pip_rc")
set(PIP_DEPLOY_TOOL "deploy_tool")
else() else()
set(PIP_CMG "${CMAKE_CURRENT_BINARY_DIR}/utils/code_model_generator/pip_cmg") set(PIP_CMG "${CMAKE_CURRENT_BINARY_DIR}/utils/code_model_generator/pip_cmg")
set(PIP_RC "${CMAKE_CURRENT_BINARY_DIR}/utils/resources_compiler/pip_rc") set(PIP_RC "${CMAKE_CURRENT_BINARY_DIR}/utils/resources_compiler/pip_rc")
set(PIP_DEPLOY_TOOL "${CMAKE_CURRENT_BINARY_DIR}/utils/deploy_tool/deploy_tool")
endif() endif()
endif() endif()
# Compiler # Compiler
get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME)
#link_directories(${CMAKE_CURRENT_BINARY_DIR})
#message("${C_COMPILER}")
# Sources
# Main lib # Main lib
set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "concurrent" "cloud") file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/lib/main/*")
if(PIP_FREERTOS) list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/lib/main")
#list(REMOVE_ITEM PIP_FOLDERS "console")
#include_directories("${PIP_SRC_MAIN}/console")
endif()
include_directories("${PIP_SRC_MAIN}")
set(PIP_MAIN_FOLDERS) set(PIP_MAIN_FOLDERS)
foreach(F ${PIP_FOLDERS}) foreach(F ${PIP_FOLDERS})
list(APPEND PIP_MAIN_FOLDERS "\"${PROJECT_SOURCE_DIR}/${PIP_SRC_MAIN}/${F}\"") if (IS_DIRECTORY "${F}")
include_directories("${PIP_SRC_MAIN}/${F}") list(APPEND PIP_MAIN_FOLDERS "${F}")
gather_src("${PIP_SRC_MAIN}/${F}" CPP_LIB_MAIN HDRS PHDRS) include_directories("${F}")
endif()
endforeach(F) endforeach(F)
# Crypt lib if (DEFINED LIBPROJECT)
gather_src("${PIP_SRC_CRYPT}" CPP_LIB_CRYPT HDRS PHDRS) set(PIP_MAIN_FOLDERS "${PIP_MAIN_FOLDERS}" PARENT_SCOPE)
endif()
# Compress lib if (TESTS)
gather_src("${PIP_SRC_COMPRESS}" CPP_LIB_COMPRESS HDRS PHDRS) set(PIP_ROOT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}")
add_subdirectory(tests)
# USB lib endif()
gather_src("${PIP_SRC_USB}" CPP_LIB_USB HDRS PHDRS)
# FFTW lib
gather_src("${PIP_SRC_FFTW}" CPP_LIB_FFTW HDRS PHDRS)
# OpenCL lib
gather_src("${PIP_SRC_OPENCL}" CPP_LIB_OPENCL HDRS PHDRS)
# IO Utils lib
gather_src("${PIP_SRC_IO_UTILS}" CPP_LIB_IO_UTILS HDRS PHDRS)
# Concurrent lib
gather_src("${PIP_SRC_CONCURRENT}" CPP_LIB_CONCURRENT HDRS PHDRS)
gather_src("${PIP_SRC_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS)
# Cloud lib
gather_src("${PIP_SRC_CLOUD}" CPP_LIB_CLOUD HDRS PHDRS)
if(PIP_FREERTOS) if(PIP_FREERTOS)
add_definitions(-DPIP_FREERTOS) add_definitions(-DPIP_FREERTOS)
@@ -258,59 +277,40 @@ CHECK_FUNCTION_EXISTS(timer_delete PIP_TIMER_RT_2)
# Check if build debug version # Check if build debug version
if (CMAKE_BUILD_TYPE MATCHES Debug) if (CMAKE_BUILD_TYPE MATCHES Debug)
set(PIP_BUILD_TYPE "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -Wall")
add_definitions(-DPIP_DEBUG) add_definitions(-DPIP_DEBUG)
message(STATUS "Building PIP debug version")
else() else()
set(PIP_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall")
message(STATUS "Building PIP release version")
endif() endif()
if (TESTS)
include(DownloadGTest)
set(CONCURRENT_TESTS 1) #"Enable tests for concurrent library"
else()
set(CONCURRENT_TESTS 0)
endif()
# Check if std::iostream operators support # Check if std::iostream operators support
set(PIP_STD_IOSTREAM "no")
if(STD_IOSTREAM) if(STD_IOSTREAM)
set(PIP_STD_IOSTREAM "yes")
add_definitions(-DPIP_STD_IOSTREAM) add_definitions(-DPIP_STD_IOSTREAM)
message(STATUS "Building PIP with std iostream operators support")
else()
message(STATUS "Building PIP without std iostream operators support")
endif()
# Check if STL containers is on (to enable use "-DSTL=" argument of cmake)
if(STL)
message(STATUS "Building PIP with STL containers")
add_definitions(-DPIP_CONTAINERS_STL)
else()
message(STATUS "Building PIP with PIP containers")
endif() endif()
# Check if ICU used for PIString and PIChar # Check if ICU used for PIString and PIChar
set(PIP_ICU "no")
if(ICU) if(ICU)
message(STATUS "Building PIP with ICU") set(PIP_ICU "yes")
add_definitions(-DPIP_ICU) add_definitions(-DPIP_ICU)
list(APPEND LIBS_MAIN icuuc) list(APPEND LIBS_MAIN icuuc)
else()
message(STATUS "Building PIP without ICU")
endif() endif()
# Check if PIP should be built with introspection # Check if PIP should be built with introspection
set(_PIP_DEFS "") set(_PIP_DEFS "")
set(_PIP_DEFS_FILE "${CMAKE_CURRENT_BINARY_DIR}/pip_defs.h") set(_PIP_DEFS_FILE "${CMAKE_CURRENT_BINARY_DIR}/pip_defs.h")
set(PIP_INTROSPECTION "no")
if(INTROSPECTION) if(INTROSPECTION)
message(STATUS "Building PIP with introspection") set(PIP_INTROSPECTION "yes")
message(STATUS "Warning: Introspection reduces the performance!")
add_definitions(-DPIP_INTROSPECTION) add_definitions(-DPIP_INTROSPECTION)
set(_PIP_DEFS "PIP_INTROSPECTION") set(_PIP_DEFS "PIP_INTROSPECTION")
else()
message(STATUS "Building PIP without introspection")
endif() endif()
if ((NOT DEFINED _PIP_SAVED_DEFS) OR (NOT "x${_PIP_SAVED_DEFS}" STREQUAL "x${_PIP_DEFS}")) if ((NOT DEFINED _PIP_SAVED_DEFS) OR (NOT "x${_PIP_SAVED_DEFS}" STREQUAL "x${_PIP_DEFS}"))
set(_PIP_SAVED_DEFS "${_PIP_DEFS}" CACHE STRING "pip_defs" FORCE) set(_PIP_SAVED_DEFS "${_PIP_DEFS}" CACHE STRING "pip_defs" FORCE)
@@ -325,10 +325,10 @@ list(APPEND HDRS ${_PIP_DEFS_FILE})
# Check if RT timers exists # Check if RT timers exists
if(PIP_TIMER_RT_0 AND PIP_TIMER_RT_1 AND PIP_TIMER_RT_2) if(PIP_TIMER_RT_0 AND PIP_TIMER_RT_1 AND PIP_TIMER_RT_2)
set(PIP_TIMERS "Thread, ThreadRT, Pool")
add_definitions(-DPIP_TIMER_RT) add_definitions(-DPIP_TIMER_RT)
message(STATUS "Building PIP with timers: Thread, ThreadRT, Pool")
else() else()
message(STATUS "Building PIP with timers: Thread, Pool") set(PIP_TIMERS "Thread, Pool")
endif() endif()
@@ -339,7 +339,6 @@ if(APPLE)
endif() endif()
if ((NOT DEFINED LIBPROJECT) AND (DEFINED ANDROID_PLATFORM)) if ((NOT DEFINED LIBPROJECT) AND (DEFINED ANDROID_PLATFORM))
include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include) include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include)
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I${ANDROID_NDK}/sysroot/usr/include")
#message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include") #message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include")
#message("${ANDROID_NDK}/sysroot/usr/include") #message("${ANDROID_NDK}/sysroot/usr/include")
endif() endif()
@@ -347,7 +346,7 @@ if(NOT PIP_FREERTOS)
if(WIN32) if(WIN32)
if(${C_COMPILER} STREQUAL "cl.exe") if(${C_COMPILER} STREQUAL "cl.exe")
else() else()
list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi) list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi cfgmgr32 setupapi)
endif() endif()
else() else()
list(APPEND LIBS_MAIN dl) list(APPEND LIBS_MAIN dl)
@@ -365,19 +364,12 @@ if(PIP_FREERTOS)
set(PIP_LIBS ${LIBS_MAIN}) set(PIP_LIBS ${LIBS_MAIN})
else() else()
foreach(LIB_ ${LIBS_MAIN}) foreach(LIB_ ${LIBS_MAIN})
find_library(${LIB_}_FOUND ${LIB_}) pip_find_lib(${LIB_})
if(${LIB_}_FOUND)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${${LIB_}_FOUND})
list(APPEND PIP_LIBS ${${LIB_}_FOUND})
endif()
endforeach() endforeach()
endif() endif()
list(APPEND LIBS_STATUS ${LIBS_MAIN})
import_version(pip PIP) import_version(pip PIP)
if(WIN32) if(WIN32)
make_rc(pip _RC)
add_definitions(-DPSAPI_VERSION=1) add_definitions(-DPSAPI_VERSION=1)
add_library(pip ${PIP_LIB_TYPE} ${CPP_LIB_MAIN} ${HDRS} ${PHDRS} ${_RC})
if(${C_COMPILER} STREQUAL "cl.exe") if(${C_COMPILER} STREQUAL "cl.exe")
set(CMAKE_CXX_FLAGS "/O2 /Ob2 /Ot /W0") set(CMAKE_CXX_FLAGS "/O2 /Ob2 /Ot /W0")
endif() endif()
@@ -385,77 +377,37 @@ else()
set(${CMAKE_CXX_FLAGS} "${CMAKE_CXX_FLAGS} -fPIC") set(${CMAKE_CXX_FLAGS} "${CMAKE_CXX_FLAGS} -fPIC")
if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
else()
endif() endif()
add_library(pip ${PIP_LIB_TYPE} ${CPP_LIB_MAIN})
endif() endif()
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
include(GenerateExportHeader)
generate_export_header(pip)
list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_export.h")
target_link_libraries(pip ${PIP_LIBS})
if (NOT PIP_FREERTOS)
# Check if USB is supported pip_module(main "${LIBS_MAIN}" "PIP main library" "" "")
find_library(usb_FOUND usb SHARED)
if (NOT CROSSTOOLS)
if (NOT PIP_FREERTOS)
pip_module(console "" "PIP console support" "" "")
pip_find_lib(usb)
if(usb_FOUND) if(usb_FOUND)
message(STATUS "Building PIP with USB support") pip_module(usb "usb" "PIP usb support" "" "")
import_version(pip_usb pip)
set_deploy_property(pip_usb ${PIP_LIB_TYPE}
LABEL "PIP usb support"
FULLNAME "${_PIP_DOMAIN}.pip_usb"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(pip_usb _RC)
add_definitions(-DPIP_USB)
add_library(pip_usb ${PIP_LIB_TYPE} ${CPP_LIB_USB} ${_RC})
target_link_libraries(pip_usb pip ${usb_FOUND})
list(APPEND LIBS_STATUS usb)
list(APPEND PIP_LIBS_TARGETS pip_usb)
else()
message(STATUS "Building PIP without USB support")
endif() endif()
# Check if PIP support cryptographic encryption/decryption using sodium library pip_find_lib(zlib NAMES z zlib)
find_library(sodium_FOUND sodium)
if(sodium_FOUND)
message(STATUS "Building PIP with crypt support")
import_version(pip_crypt pip)
set_deploy_property(pip_crypt ${PIP_LIB_TYPE}
LABEL "PIP crypt support"
FULLNAME "${_PIP_DOMAIN}.pip_crypt"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(pip_crypt _RC)
add_definitions(-DPIP_CRYPT)
add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT} ${_RC})
target_link_libraries(pip_crypt pip ${sodium_FOUND})
list(APPEND LIBS_STATUS sodium)
list(APPEND PIP_LIBS_TARGETS pip_crypt)
else()
message(STATUS "Building PIP without crypt support")
endif()
# Check if PIP support compress/decompress using zlib library
find_library(zlib_FOUND NAMES z zlib)
if(zlib_FOUND) if(zlib_FOUND)
message(STATUS "Building PIP with zlib compress support") pip_module(compress "zlib" "PIP compression support" "" "")
import_version(pip_compress pip) endif()
set_deploy_property(pip_compress ${PIP_LIB_TYPE}
LABEL "PIP compression support"
FULLNAME "${_PIP_DOMAIN}.pip_compress" pip_find_lib(sodium)
COMPANY "${_PIP_COMPANY}" if(sodium_FOUND)
INFO "Platform-Independent Primitives") pip_module(crypt "sodium" "PIP crypt support" "" "")
make_rc(pip_compress _RC) pip_module(cloud "pip_crypt" "PIP cloud support" "" "")
add_definitions(-DPIP_COMPRESS)
add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS} ${_RC})
target_link_libraries(pip_compress pip ${zlib_FOUND})
list(APPEND LIBS_STATUS zlib)
list(APPEND PIP_LIBS_TARGETS pip_compress)
else()
message(STATUS "Building PIP without compress support")
endif() endif()
@@ -465,7 +417,6 @@ if (NOT PIP_FREERTOS)
set(FFTW_LIB_SUFFIXES2 "" "-3") set(FFTW_LIB_SUFFIXES2 "" "-3")
set(FFTW_LIBS) set(FFTW_LIBS)
set(FFTW_ABS_LIBS) set(FFTW_ABS_LIBS)
set(PIP_FFTW_FOUND)
set(CMAKE_REQUIRED_INCLUDES fftw3.h) set(CMAKE_REQUIRED_INCLUDES fftw3.h)
foreach(FFTW_S_ IN LISTS FFTW_LIB_SUFFIXES) foreach(FFTW_S_ IN LISTS FFTW_LIB_SUFFIXES)
set(FFTW_BREAK false) set(FFTW_BREAK false)
@@ -473,140 +424,63 @@ if (NOT PIP_FREERTOS)
if(NOT FFTW_BREAK) if(NOT FFTW_BREAK)
set(FFTW_CLN "${FFTW_LIB_NAME}${FFTW_S_}${FFTW_S2_}") set(FFTW_CLN "${FFTW_LIB_NAME}${FFTW_S_}${FFTW_S2_}")
set(FFTW_CLNT "${FFTW_LIB_NAME}${FFTW_S_}_threads${FFTW_S2_}") set(FFTW_CLNT "${FFTW_LIB_NAME}${FFTW_S_}_threads${FFTW_S2_}")
find_library(${FFTW_CLN}_FOUND ${FFTW_CLN}) find_library(${FFTW_CLN}_LIBRARIES ${FFTW_CLN})
find_library(${FFTW_CLNT}_FOUND ${FFTW_CLNT}) find_library(${FFTW_CLNT}_LIBRARIES ${FFTW_CLNT})
if(${FFTW_CLN}_FOUND) set(${FFTW_CLN}_FOUND FALSE)
set(${FFTW_CLNT}_FOUND FALSE)
if(${FFTW_CLN}_LIBRARIES)
set(${FFTW_CLN}_FOUND TRUE)
list(APPEND FFTW_LIBS "${FFTW_CLN}") list(APPEND FFTW_LIBS "${FFTW_CLN}")
list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_FOUND}") list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_LIBRARIES}")
#message(STATUS "PIFFTW found ${FFTW_CLN} = ${${FFTW_CLN}_FOUND}")
set(${FFTW_CLN}_CTS "${FFTW_CLN}") set(${FFTW_CLN}_CTS "${FFTW_CLN}")
if(${FFTW_CLNT}_FOUND) if(${FFTW_CLNT}_FLIBRARIES)
set(${FFTW_CLNT}_FOUND TRUE)
list(APPEND FFTW_LIBS "${FFTW_CLNT}") list(APPEND FFTW_LIBS "${FFTW_CLNT}")
list(APPEND FFTW_ABS_LIBS "${${FFTW_CLNT}_FOUND}") list(APPEND FFTW_ABS_LIBS "${${FFTW_CLNT}_LIBRARIES}")
list(APPEND ${FFTW_CLN}_CTS "${FFTW_CLNT}") list(APPEND ${FFTW_CLN}_CTS "${FFTW_CLNT}")
endif() endif()
set(CMAKE_REQUIRED_LIBRARIES ${${FFTW_CLN}_CTS}) set(CMAKE_REQUIRED_LIBRARIES ${${FFTW_CLN}_CTS})
CHECK_FUNCTION_EXISTS(fftw${FFTW_S_}_make_planner_thread_safe ${FFTW_CLN}_TSFE) CHECK_FUNCTION_EXISTS(fftw${FFTW_S_}_make_planner_thread_safe ${FFTW_CLN}_TSFE)
add_definitions(-DPIP_FFTW${FFTW_S_}) add_definitions(-DPIP_FFTW${FFTW_S_})
set(PIP_FFTW_FOUND true)
if(${FFTW_CLN}_TSFE) if(${FFTW_CLN}_TSFE)
add_definitions(-DPIP_FFTW${FFTW_S_}_THREADSAFE) add_definitions(-DPIP_FFTW${FFTW_S_}_THREADSAFE)
else() else()
message(STATUS "Warning: PIFFTW${FFTW_S_}::preparePlan was not threadsafe") message(STATUS "Warning: PIFFTW${FFTW_S_}::preparePlan was not threadsafe")
endif() endif()
#message(STATUS "${FFTW_CLN} -> ${${FFTW_CLN}_TSFE}")
endif() endif()
endif() endif()
endforeach() endforeach()
endforeach() endforeach()
if(FFTW_LIBS) if(FFTW_LIBS)
message(STATUS "Building PIP with fftw3 support: ${FFTW_LIBS}") pip_module(fftw "${FFTW_LIBS}" "PIP FFTW support" "" "")
import_version(pip_fftw pip)
set_deploy_property(pip_fftw ${PIP_LIB_TYPE}
LABEL "PIP FFTW support"
FULLNAME "${_PIP_DOMAIN}.pip_fftw"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(pip_fftw _RC)
add_library(pip_fftw ${PIP_LIB_TYPE} ${CPP_LIB_FFTW} ${_RC})
target_link_libraries(pip_fftw pip ${FFTW_ABS_LIBS})
list(APPEND LIBS_STATUS ${FFTW_LIBS})
list(APPEND PIP_LIBS_TARGETS pip_fftw)
else()
message(STATUS "Building PIP without fftw3 support")
endif() endif()
# Check if PIP support OpenCL find_package(OpenCL QUIET) #OpenCL_VERSION_STRING
find_package(OpenCL QUIET)
if(OpenCL_FOUND) if(OpenCL_FOUND)
message(STATUS "Building PIP with OpenCL support") set(_opencl_lib OpenCL::OpenCL)
import_version(pip_opencl pip)
set_deploy_property(pip_opencl ${PIP_LIB_TYPE}
LABEL "PIP OpenCL support"
FULLNAME "${_PIP_DOMAIN}.pip_opencl"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(pip_opencl _RC)
if(APPLE)
include_directories(${OpenCL_INCLUDE_DIRS}/Headers)
else()
include_directories(${OpenCL_INCLUDE_DIRS})
endif()
add_definitions(-DPIP_OPENCL)
pip_resources(CL_RES "src_opencl/resources.conf")
add_library(pip_opencl ${PIP_LIB_TYPE} ${CPP_LIB_OPENCL} ${CL_RES} ${_RC})
add_dependencies(pip_opencl pip_rc)
if(${CMAKE_VERSION} VERSION_LESS "3.7.0") if(${CMAKE_VERSION} VERSION_LESS "3.7.0")
target_link_libraries(pip_opencl pip OpenCL) target_link_libraries(_opencl_lib OpenCL)
else()
target_link_libraries(pip_opencl pip OpenCL::OpenCL)
endif() endif()
list(APPEND LIBS_STATUS OpenCL) pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "" " (${OpenCL_VERSION_STRING})")
list(APPEND PIP_LIBS_TARGETS pip_opencl)
set(OpenCL_FOUND ${OpenCL_LIBRARIES})
else()
message(STATUS "Building PIP without OpenCL support")
endif() endif()
# Check if PIP IO Utils library supports crypt
set(IO_UTILS_LIBS pip)
import_version(pip_io_utils pip)
set_deploy_property(pip_io_utils ${PIP_LIB_TYPE}
LABEL "PIP I/O utilites"
FULLNAME "${_PIP_DOMAIN}.pip_io_utils"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(pip_io_utils _RC)
add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS} ${_RC})
if(sodium_FOUND) if(sodium_FOUND)
message(STATUS "Building PIP IO Utils library with crypt support") pip_module(io_utils "pip_crypt" "PIP I/O support" "" " (+crypt)")
list(APPEND IO_UTILS_LIBS pip_crypt)
else() else()
message(STATUS "Building PIP IO Utils library without crypt support, attention!") pip_module(io_utils "" "PIP I/O support" "" "")
endif()
target_link_libraries(pip_io_utils ${IO_UTILS_LIBS})
list(APPEND PIP_LIBS_TARGETS pip_io_utils)
# Concurrent module
set(CONCURRENT_LIBS pip)
import_version(pip_concurrent pip)
set_deploy_property(pip_concurrent ${PIP_LIB_TYPE}
LABEL "PIP concurrent support"
FULLNAME "${_PIP_DOMAIN}.pip_concurrent"
COMPANY "${_PIP_COMPANY}"
INFO "Platform-Independent Primitives")
make_rc(pip_concurrent _RC)
add_library(pip_concurrent ${PIP_LIB_TYPE} ${CPP_LIB_CONCURRENT} ${_RC})
target_link_libraries(pip_concurrent ${CONCURRENT_LIBS})
set_property(TARGET pip_concurrent PROPERTY CXX_STANDARD 11)
list(APPEND PIP_LIBS_TARGETS pip_concurrent)
# Enable build tests for concurrent module
if(CONCURRENT_TESTS)
add_executable(pip_concurrent_test ${CPP_CONCURRENT_TEST})
target_link_libraries(pip_concurrent_test gtest_main gmock_main pip_concurrent)
add_test(NAME pip_concurrent_test COMMAND tests)
add_custom_target(pip_concurrent_test_perform ALL COMMAND pip_concurrent_test)
endif() endif()
# Build cloud library if crypt enabled # Check Lua support
if(sodium_FOUND) if(MINGW)
message(STATUS "Building PICloud support") set(LUA_INCLUDE_DIR ${MINGW_INCLUDE})
import_version(pip_cloud pip) endif()
set_deploy_property(pip_cloud ${PIP_LIB_TYPE} find_package(Lua QUIET)
LABEL "PIP cloud transport support" if (LUA_FOUND)
FULLNAME "${_PIP_DOMAIN}.pip_cloud" pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd" " (${LUA_VERSION_STRING})")
COMPANY "${_PIP_COMPANY}" list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge")
INFO "Platform-Independent Primitives")
make_rc(pip_cloud _RC)
add_definitions(-DPIP_CLOUD)
add_library(pip_cloud ${PIP_LIB_TYPE} ${CPP_LIB_CLOUD} ${_RC})
target_link_libraries(pip_cloud pip pip_crypt)
list(APPEND PIP_LIBS_TARGETS pip_cloud)
endif() endif()
@@ -614,87 +488,101 @@ if (NOT PIP_FREERTOS)
if(PIP_UTILS) if(PIP_UTILS)
add_executable(pip_test "main.cpp") add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip) target_link_libraries(pip_test pip)
if (LUA_FOUND)
target_link_libraries(pip_test pip_lua ${LUA_LIBRARIES})
endif()
endif() endif()
else(NOT PIP_FREERTOS) else()
message(STATUS "Building PIP with crypt support")
set(PIP_MSG_crypt "yes")
set(PIP_MSG_compress "yes")
set(PIP_MODULES pip)
add_definitions(-DPIP_CRYPT) add_definitions(-DPIP_CRYPT)
add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT}) add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT})
target_link_libraries(pip_crypt pip) target_link_libraries(pip_crypt pip)
list(APPEND PIP_LIBS_TARGETS pip_crypt) list(APPEND PIP_MODULES pip_crypt)
set(IO_UTILS_LIBS pip) set(IO_UTILS_LIBS pip)
add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS}) add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS})
message(STATUS "Building PIP IO Utils library with crypt support")
list(APPEND IO_UTILS_LIBS pip_crypt) list(APPEND IO_UTILS_LIBS pip_crypt)
target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) target_link_libraries(pip_io_utils ${IO_UTILS_LIBS})
list(APPEND PIP_LIBS_TARGETS pip_io_utils) list(APPEND PIP_MODULES pip_io_utils)
message(STATUS "Building PIP with zlib compress support")
add_definitions(-DPIP_COMPRESS) add_definitions(-DPIP_COMPRESS)
add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS}) add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS})
target_link_libraries(pip_compress pip) target_link_libraries(pip_compress pip)
list(APPEND PIP_LIBS_TARGETS pip_compress) list(APPEND PIP_MODULES pip_compress)
endif(NOT PIP_FREERTOS)
endif()
endif()
string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}")
target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"")
# Install # Install
# Check if system or local install will be used (to system install use "-DLIB=" argument of cmake) # Check if system or local install will be used (to system install use "-DLIB=" argument of cmake)
if(LIB) if(LIB)
if(WIN32) if(WIN32)
if(MINGW) if(MINGW)
if (NOT CROSSTOOLS)
install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
install(TARGETS ${PIP_LIBS_TARGETS} ARCHIVE DESTINATION ${MINGW_LIB}) install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip)
install(TARGETS ${PIP_LIBS_TARGETS} RUNTIME DESTINATION ${MINGW_BIN}) if(HDR_DIRS)
install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip)
endif()
install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION ${MINGW_LIB})
endif()
install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION ${MINGW_BIN})
find_library(STDLIB "stdc++-6" PATHS ${MINGW_BIN} NO_DEFAULT_PATH) find_library(STDLIB "stdc++-6" PATHS ${MINGW_BIN} NO_DEFAULT_PATH)
find_library(STDLIB "stdc++-6") find_library(STDLIB "stdc++-6")
#message("${STDLIB}") #message("${STDLIB}")
if (STDLIB) if (STDLIB)
file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/code_model_generator") file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/code_model_generator")
file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/resources_compiler") file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/resources_compiler")
file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/deploy_tool")
endif() endif()
else() else()
#message("${CMAKE_CURRENT_BINARY_DIR}/pip_export.h")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pip_export.h DESTINATION include) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pip_export.h DESTINATION include)
endif() endif()
else() else()
if (NOT CROSSTOOLS)
install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) if(HDR_DIRS)
install(DIRECTORY ${HDR_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip)
endif()
endif()
install(TARGETS ${PIP_MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif() endif()
message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"")
# Precompiled header
#add_custom_target(pip_pch ALL COMMAND ${CMAKE_CXX_COMPILER} -O2 -fPIC -g3 ${CMAKE_INSTALL_PREFIX}/include/pip/pip.h DEPENDS pip SOURCES ${HDRS})
#list(APPEND HDRS "pip.h.gch")
file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in" "cmake/android_debug.keystore") file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in" "cmake/android_debug.keystore")
install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules)
else() else()
if(NOT PIP_FREERTOS) if(NOT PIP_FREERTOS)
if(WIN32) if(WIN32)
install(TARGETS ${PIP_LIBS_TARGETS} RUNTIME DESTINATION bin) install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin)
install(TARGETS ${PIP_LIBS_TARGETS} ARCHIVE DESTINATION lib) install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib)
else() else()
install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION lib) install(TARGETS ${PIP_MODULES} DESTINATION lib)
endif() endif()
install(FILES ${HDRS} DESTINATION include/pip) install(FILES ${HDRS} DESTINATION include/pip)
message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") if(HDR_DIRS)
install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip)
endif()
endif() endif()
endif() endif()
# foreach(_T ${PIP_LIBS_TARGETS})
# apple_rpath_patch(${_T})
# endforeach()
if(NOT PIP_FREERTOS) if(NOT PIP_FREERTOS)
# Auxiliary # Auxiliary
add_subdirectory("${PIP_SRC_MAIN}/auxiliary/piterminal") if (NOT CROSSTOOLS)
add_subdirectory("utils/piterminal")
endif()
# Utils # Utils
add_subdirectory("utils/code_model_generator") add_subdirectory("utils/code_model_generator")
add_subdirectory("utils/resources_compiler") add_subdirectory("utils/resources_compiler")
if(PIP_UTILS)
add_subdirectory("utils/system_test")
add_subdirectory("utils/remote_console")
add_subdirectory("utils/udp_file_transfer")
add_subdirectory("utils/deploy_tool") add_subdirectory("utils/deploy_tool")
if(PIP_UTILS AND (NOT CROSSTOOLS))
add_subdirectory("utils/system_test")
add_subdirectory("utils/udp_file_transfer")
if(sodium_FOUND) if(sodium_FOUND)
add_subdirectory("utils/system_daemon") add_subdirectory("utils/system_daemon")
add_subdirectory("utils/crypt_tool") add_subdirectory("utils/crypt_tool")
@@ -706,54 +594,25 @@ endif()
# Libraries messages # Libraries messages
message(STATUS "Building PIP modules: ${PIP_LIBS_TARGETS}")
if(DEFINED LIBPROJECT) if(DEFINED LIBPROJECT)
set(PIP_LIBS_TARGETS ${PIP_LIBS_TARGETS} PARENT_SCOPE) set(PIP_MODULES ${PIP_MODULES} PARENT_SCOPE)
list(APPEND _ALL_TARGETS ${PIP_LIBS_TARGETS}) list(APPEND _ALL_TARGETS ${PIP_MODULES})
set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE)
endif() endif()
if(NOT PIP_FREERTOS)
foreach(LIB_ ${LIBS_STATUS})
message(STATUS "Library ${LIB_} -> " ${${LIB_}_FOUND})
if(NOT ${LIB_}_FOUND)
message(WARNING "Library ${LIB_} not found, please install it")
endif()
endforeach()
endif()
# #
# Build Documentation # Build Documentation
# #
if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
# find_package(Doxygen QUIET)
# if(Doxygen_FOUND)
# message(STATUS "Building PIP with documentation via Doxygen")
# #set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in)
# set(DOXYFILE ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile)
# #configure_file(${DOXYFILE_IN} ${DOXYFILE} @ONLY)
# add_custom_target(DOC
# COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE}
# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
# COMMENT "Generating API documentation with Doxygen"
# VERBATIM)
# add_custom_command(TARGET DOC
# POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/source/doc/Documentation.html ${CMAKE_SOURCE_DIR}/doc
# )
# install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc)
# endif()
if (NOT PIP_FREERTOS)
include(PIPDocumentation) include(PIPDocumentation)
find_package(Doxygen) find_package(Doxygen)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
set(DOXY_PROJECT_NUMBER "${PIP_VERSION}") set(DOXY_PROJECT_NUMBER "${PIP_VERSION}")
set(DOXY_QHP_CUST_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"") set(DOXY_QHP_CUST_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"")
set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"") set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"")
set(DOXY_EXAMPLE_PATH "\"${PROJECT_SOURCE_DIR}/doc/examples\"") set(DOXY_EXAMPLE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/examples\"")
set(DOXY_IMAGE_PATH "\"${PROJECT_SOURCE_DIR}/doc/images\"") set(DOXY_IMAGE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/images\"")
set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd\"")
if(DOXYGEN_DOT_EXECUTABLE) if(DOXYGEN_DOT_EXECUTABLE)
string(REPLACE "\\" "" _DOT_PATH "${DOXYGEN_DOT_PATH}") string(REPLACE "\\" "" _DOT_PATH "${DOXYGEN_DOT_PATH}")
set(DOXY_DOT_PATH "\"${_DOT_PATH}\"") set(DOXY_DOT_PATH "\"${_DOT_PATH}\"")
@@ -761,13 +620,70 @@ if (NOT PIP_FREERTOS)
set(DOXY_DIA_PATH "\"${_DOT_PATH}\"") set(DOXY_DIA_PATH "\"${_DOT_PATH}\"")
endif() endif()
set(DOXY_INPUT) set(DOXY_INPUT)
foreach(F ${PIP_SRC_DIRS}) foreach(F ${PIP_MAIN_FOLDERS})
list(APPEND DOXY_INPUT "\"${PROJECT_SOURCE_DIR}/${F}\"") list(APPEND DOXY_INPUT "\"${F}\"")
endforeach(F) endforeach(F)
string(REPLACE ";" " " DOXY_INPUT "${DOXY_INPUT}") string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/lib\"")
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${PIP_MAIN_FOLDERS}") string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}")
add_documentation(doc Doxyfile.in) string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS")
add_documentation(doc doc/Doxyfile.in)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL)
endif() endif()
endif() endif()
list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES})
message("----------PIP----------")
message(" Version: ${PIP_VERSION} ")
message(" Linkage: ${PIP_LIB_TYPE_MSG}")
message(" Type : ${PIP_BUILD_TYPE}")
if(LIB)
message(" Install: \"${CMAKE_INSTALL_PREFIX}\"")
else()
if(NOT PIP_FREERTOS)
message(" Install: local \"bin\", \"lib\" and \"include\"")
endif()
endif()
message("")
message(" Options:")
message(" std::iostream: ${PIP_STD_IOSTREAM}")
message(" ICU strings : ${PIP_ICU}")
message(" Timer types : ${PIP_TIMERS}")
message(" Introspection: ${PIP_INTROSPECTION}")
if(INTROSPECTION)
message(STATUS " Warning: Introspection reduces the performance!")
endif()
message("")
message(" Modules:")
foreach(_m ${PIP_SRC_MODULES})
message(" ${_m}: ${PIP_MSG_${_m}}")
endforeach()
message("")
if (PIP_TESTS_LIST)
message(" Tests:")
foreach(_test ${PIP_TESTS_LIST})
message(" * ${_test}")
endforeach()
else()
message(" Tests: skip (tests off)")
endif()
message("")
message(" Utilites:")
foreach(_util ${PIP_UTILS_LIST})
message(" * ${_util}")
endforeach()
if(NOT PIP_FREERTOS)
message("")
message(" Using libraries:")
foreach(LIB_ ${LIBS_STATUS})
if (NOT TARGET ${LIB_})
if(${LIB_}_FOUND)
message(" ${LIB_} -> ${${LIB_}_LIBRARIES}")
else()
message(" ${LIB_} not found, may fail")
endif()
endif()
endforeach()
endif()
message("-----------------------")

View File

@@ -1,674 +1,165 @@
GNU GENERAL PUBLIC LICENSE GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007 Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
Preamble
This version of the GNU Lesser General Public License incorporates
The GNU General Public License is a free, copyleft license for the terms and conditions of version 3 of the GNU General Public
software and other kinds of works. License, supplemented by the additional permissions listed below.
The licenses for most software and other practical works are designed 0. Additional Definitions.
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to As used herein, "this License" refers to version 3 of the GNU Lesser
share and change all versions of a program--to make sure it remains free General Public License, and the "GNU GPL" refers to version 3 of the GNU
software for all its users. We, the Free Software Foundation, use the General Public License.
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to "The Library" refers to a covered work governed by this License,
your programs, too. other than an Application or a Combined Work as defined below.
When we speak of free software, we are referring to freedom, not An "Application" is any work that makes use of an interface provided
price. Our General Public Licenses are designed to make sure that you by the Library, but which is not otherwise based on the Library.
have the freedom to distribute copies of free software (and charge for Defining a subclass of a class defined by the Library is deemed a mode
them if you wish), that you receive source code or can get it if you of using an interface provided by the Library.
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things. A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
To protect your rights, we need to prevent others from denying you with which the Combined Work was made is also called the "Linked
these rights or asking you to surrender the rights. Therefore, you have Version".
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others. The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
For example, if you distribute copies of such a program, whether for portions of the Combined Work that, considered in isolation, are
gratis or for a fee, you must pass on to the recipients the same based on the Application, and not on the Linked Version.
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they The "Corresponding Application Code" for a Combined Work means the
know their rights. object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Developers that use the GNU GPL protect your rights with two steps: Application, but excluding the System Libraries of the Combined Work.
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it. 1. Exception to Section 3 of the GNU GPL.
For the developers' and authors' protection, the GPL clearly explains You may convey a covered work under sections 3 and 4 of this License
that there is no warranty for this free software. For both users' and without being bound by section 3 of the GNU GPL.
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to 2. Conveying Modified Versions.
authors of previous versions.
If you modify a copy of the Library, and, in your modifications, a
Some devices are designed to deny users access to install or run facility refers to a function or data to be supplied by an Application
modified versions of the software inside them, although the manufacturer that uses the facility (other than as an argument passed when the
can do so. This is fundamentally incompatible with the aim of facility is invoked), then you may convey a copy of the modified
protecting users' freedom to change the software. The systematic version:
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we a) under this License, provided that you make a good faith effort to
have designed this version of the GPL to prohibit the practice for those ensure that, in the event an Application does not supply the
products. If such problems arise substantially in other domains, we function or data, the facility still operates, and performs
stand ready to extend this provision to those domains in future versions whatever part of its purpose remains meaningful, or
of the GPL, as needed to protect the freedom of users.
b) under the GNU GPL, with none of the additional permissions of
Finally, every program is threatened constantly by software patents. this License applicable to that copy.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to 3. Object Code Incorporating Material from Library Header Files.
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that The object code form of an Application may incorporate material from
patents cannot be used to render the program non-free. a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
The precise terms and conditions for copying, distribution and material is not limited to numerical parameters, data structure
modification follow. layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
TERMS AND CONDITIONS
a) Give prominent notice with each copy of the object code that the
0. Definitions. Library is used in it and that the Library and its use are
covered by this License.
"This License" refers to version 3 of the GNU General Public License.
b) Accompany the object code with a copy of the GNU GPL and this license
"Copyright" also means copyright-like laws that apply to other kinds of document.
works, such as semiconductor masks.
4. Combined Works.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and You may convey a Combined Work under terms of your choice that,
"recipients" may be individuals or organizations. taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
To "modify" a work means to copy from or adapt all or part of the work engineering for debugging such modifications, if you also do each of
in a fashion requiring copyright permission, other than the making of an the following:
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work. a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
A "covered work" means either the unmodified Program or a work based covered by this License.
on the Program.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
To "propagate" a work means to do anything with it that, without document.
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a c) For a Combined Work that displays copyright notices during
computer or modifying a private copy. Propagation includes copying, execution, include the copyright notice for the Library among
distribution (with or without modification), making available to the these notices, as well as a reference directing the user to the
public, and in some countries other activities as well. copies of the GNU GPL and this license document.
To "convey" a work means any kind of propagation that enables other d) Do one of the following:
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying. 0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
An interactive user interface displays "Appropriate Legal Notices" suitable for, and under terms that permit, the user to
to the extent that it includes a convenient and prominently visible recombine or relink the Application with a modified version of
feature that (1) displays an appropriate copyright notice, and (2) the Linked Version to produce a modified Combined Work, in the
tells the user that there is no warranty for the work (except to the manner specified by section 6 of the GNU GPL for conveying
extent that warranties are provided), that licensees may convey the Corresponding Source.
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a 1) Use a suitable shared library mechanism for linking with the
menu, a prominent item in the list meets this criterion. Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
1. Source Code. system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
The "source code" for a work means the preferred form of the work Version.
for making modifications to it. "Object code" means any non-source
form of a work. e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
A "Standard Interface" means an interface that either is an official GNU GPL, and only to the extent that such information is
standard defined by a recognized standards body, or, in the case of necessary to install and execute a modified version of the
interfaces specified for a particular programming language, one that Combined Work produced by recombining or relinking the
is widely used among developers working in that language. Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
The "System Libraries" of an executable work include anything, other the Minimal Corresponding Source and Corresponding Application
than the work as a whole, that (a) is included in the normal form of Code. If you use option 4d1, you must provide the Installation
packaging a Major Component, but which is not part of that Major Information in the manner specified by section 6 of the GNU GPL
Component, and (b) serves only to enable use of the work with that for conveying Corresponding Source.)
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A 5. Combined Libraries.
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system You may place library facilities that are a work based on the
(if any) on which the executable work runs, or a compiler used to Library side by side in a single library together with other library
produce the work, or an object code interpreter used to run it. facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
The "Corresponding Source" for a work in object code form means all choice, if you do both of the following:
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to a) Accompany the combined library with a copy of the same work based
control those activities. However, it does not include the work's on the Library, uncombined with any other library facilities,
System Libraries, or general-purpose tools or generally available free conveyed under the terms of this License.
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source b) Give prominent notice with the combined library that part of it
includes interface definition files associated with source files for is a work based on the Library, and explaining where to find the
the work, and the source code for shared libraries and dynamically accompanying uncombined form of the same work.
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those 6. Revised Versions of the GNU Lesser General Public License.
subprograms and other parts of the work.
The Free Software Foundation may publish revised and/or new versions
The Corresponding Source need not include anything that users of the GNU Lesser General Public License from time to time. Such new
can regenerate automatically from other parts of the Corresponding versions will be similar in spirit to the present version, but may
Source. differ in detail to address new problems or concerns.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General Library as you received it specifies that a certain numbered version
Public License "or any later version" applies to it, you have the of the GNU Lesser General Public License "or any later version"
option of following the terms and conditions either of that numbered applies to it, you have the option of following the terms and
version or of any later version published by the Free Software conditions either of that published version or of any later version
Foundation. If the Program does not specify a version number of the published by the Free Software Foundation. If the Library as you
GNU General Public License, you may choose any version ever published received it does not specify a version number of the GNU Lesser
by the Free Software Foundation. General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future If the Library as you received it specifies that a proxy can decide
versions of the GNU General Public License can be used, that proxy's whether future versions of the GNU Lesser General Public License shall
public statement of acceptance of a version permanently authorizes you apply, that proxy's public statement of acceptance of any version is
to choose that version for the Program. permanent authorization for you to choose that version for the
Library.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 3 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, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

View File

@@ -1,5 +1,7 @@
# Platform-Independent Primitives library # Platform-Independent Primitives library
## Introduction ## Introduction
Low-level C++ library that covers next areas: Low-level C++ library that covers next areas:
* Strings * Strings
* Console IO * Console IO
@@ -12,16 +14,23 @@ Low-level C++ library that covers next areas:
* Compression (zlib) * Compression (zlib)
* Resources * Resources
* Metaprogramming * Metaprogramming
## CMake ## CMake
This library tightly integrated with CMake by providing some macro: This library tightly integrated with CMake by providing some macro:
* pip_code_model(<out_var> file0 [file1 ...] [OPTIONS opt0 [opt1 ...] ] [ABSOLUTE])
Generate code model files for source files file0 [file1 ...]
Options you can see by exec "pip_cmg -h" * `pip_code_model(<out_var> file0 [file1 ...] [OPTIONS opt0 [opt1 ...] ] [ABSOLUTE])`
If not ABSOLUTE source files will be prepended by CMAKE_CURRENT_SOURCE_DIR Generate code model files for source files file0 [file1 ...].
You should add ${<out_var>} to your target
* pip_resources(<out_var> file) Options you can see by exec "pip_cmg -h".
If not ABSOLUTE source files will be prepended by ${CMAKE_CURRENT_SOURCE_DIR}.
You should add ${<out_var>} to your target.
Generate C++ files for resource file * `pip_resources(<out_var> file)`
You should add ${<out_var>} to your target
Generate C++ files for resource file.
You should add ${<out_var>} to your target.
## Documentation
[Online documentation](https://shs.tools/pip/html/index.html)

24
clean
View File

@@ -1,24 +0,0 @@
#! /bin/sh
VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd utils/system_test
VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd ../../
cd utils/system_daemon
VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd ../../
cd utils/remote_console
VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd ../../
cd utils/code_model_generator
VERBOSE=1 make clean
rm -rvf ./CMakeFiles
rm -vf ./CMakeCache.txt ./Makefile ./cmake_install.cmake ./install_manifest.txt ./*~ ./*cxx ./moc_* ./*.o ./core
cd ../../

View File

@@ -1,34 +0,0 @@
#make clean
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd utils\system_test
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
cd ..
cd utils\remote_console
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
cd ..
cd utils\code_model_generator
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
cd ..
cd utils\system_daemon
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
cd ..
cd utils\udp_file_transfer
del /q /f /s CMakeFiles
rmdir /q /s CMakeFiles
del /q /f CMakeCache.txt Makefile cmake_install.cmake install_manifest.txt *~ *cxx moc_* *.o *.exe *.a *.dll *.lib core
cd ..
cd ..

View File

@@ -69,19 +69,28 @@ before call this macro, see
deploy_target(<target> [DEPLOY_DIR <dir>] [DESTINATION <dir>] deploy_target(<target> [DEPLOY_DIR <dir>]
[DESTINATION <dir>]
[RESOURCES <dir|file> [<dir|file> ...] ] [RESOURCES <dir|file> [<dir|file> ...] ]
[PLUGINS <dir|file> [<dir|file> ...] ] [PLUGINS <dir|file> [<dir|file> ...] ]
[FILES <dir|file> [<dir|file> ...] ] [FILES <dir|file> [<dir|file> ...] ]
[OPTIONS <flag> ...] [VERBOSE]) [LIBS <dir|file> [<dir|file> ...] ]
[OPTIONS <flag> ...]
[VERBOSE]
[DMG_NO_ZIP]
[DEB_USR_DIR] [DEB_ADD_SERVICE])
Create make target "deploy_<target>", depends on target "deploy" Create make target "deploy_<target>", depends on target "deploy".
On this target create release package, containing all dependencies: On this target create release package, containing all dependencies:
*.zip on Windows, *.deb on Linux and *.dmg an MacOS * .zip on Windows
* .deb on Linux
* .dmg[.zip] on MacOS
* .apk/.aab on Android
If not defined DMG_NO_ZIP then *.dmg.zip will be created on MacOS.
You should set version and deploy properties You should set version and deploy properties
before call this macro, see before call this macro, see
"set_version()" and "set_deploy_property()" "set_version()" and "set_deploy_property()".
Example: Example:
deploy_target(my_app DESTINATION packages) deploy_target(my_app DESTINATION packages)
@@ -92,17 +101,19 @@ DEPLOY_DIR - dir where you install
* <T>.app directory with executable on MacOS * <T>.app directory with executable on MacOS
DESTINATION - dir where macro place package DESTINATION - dir where macro place package
RESOURCES, PLUGINS and FILES - list of directories and files, copied to: RESOURCES, PLUGINS and FILES - list of directories and files, copied to:
| Windows | Linux | MacOS | | Windows | Linux | Linux (DEB_USR_DIR) | MacOS |
----------|---------|---------------------------|------------------- |-----------|---------|-------------------------|---------------------------|---------------------|
RESOURCES | root | /usr/share/COMPANY/target | Contents/Resources | RESOURCES | root | /opt/COMPANY/target | /usr/share/COMPANY/target | Contents/Resources |
PLUGINS | root | /usr/lib/COMPANY/target | Contents/PlugIns | PLUGINS | root | /opt/COMPANY/target | /usr/lib/COMPANY/target | Contents/PlugIns |
FILES | root | /usr/bin | Contents/MacOS | FILES | root | /opt/COMPANY/target | /usr/bin | Contents/MacOS |
| LIBS | root | /opt/COMPANY/target/lib | /usr/lib | Contents/Frameworks |
Relative paths are taken from DEPLOY_DIR Relative paths are taken from DEPLOY_DIR
Also check library dependencies from PLUGINS and FILES Also check library dependencies from PLUGINS and FILES
Important! RESOURCES, PLUGINS and FILES lists check Important! RESOURCES, PLUGINS, FILES and LIBS lists check
at cmake-time, so if entry ends with "/" it treat at cmake-time, so if entry ends with "/" it treat
as directory, else - file as directory, else - file
@@ -118,6 +129,13 @@ depends on target platform
DEPLOY_ADD_LIBPATH variable used as additional DEPLOY_ADD_LIBPATH variable used as additional
library search path library search path
If DEB_ADD_SERVICE then <T>-service.deb package will be created.
This package use contents of CMAKE_CURRENT_SOURCE_DIR/debian-service directory:
* CMAKE_CURRENT_SOURCE_DIR/debian-service/DEBIAN/
* CMAKE_CURRENT_SOURCE_DIR/debian-service/*.service
.service file placed in /opt/COMPANY/target, you should copy it to system with script
You can use "postinst,postrm,preinst,prerm,config" files to configure service
]] ]]
@@ -129,7 +147,7 @@ if (POLICY CMP0053)
cmake_policy(SET CMP0053 NEW) cmake_policy(SET CMP0053 NEW)
endif() endif()
set(__prop_names "LABEL;FULLNAME;COMPANY;ICON;INFO") set(__prop_names "LABEL;FULLNAME;COMPANY;ICON;INFO")
list(APPEND __prop_names "ANDROID_TARGET_SDK;ANDROID_STORE_FILE;ANDROID_STORE_PASSWORD;ANDROID_KEY_PASSWORD;ANDROID_KEY_ALIAS") list(APPEND __prop_names "ANDROID_TARGET_SDK;ANDROID_STORE_FILE;ANDROID_STORE_PASSWORD;ANDROID_KEY_PASSWORD;ANDROID_KEY_ALIAS;ANDROID_NEW_LOADER")
set(__version_names "MAJOR;MINOR;REVISION;BUILD;SUFFIX") set(__version_names "MAJOR;MINOR;REVISION;BUILD;SUFFIX")
include(TargetArch) include(TargetArch)
if (NOT MY_ARCH) if (NOT MY_ARCH)
@@ -365,13 +383,19 @@ endmacro()
macro(__add_file_or_dir _DIR_VAR _FILE_VAR _PATH _RELPATH) macro(__add_file_or_dir _DIR_VAR _FILE_VAR _PATH _RELPATH)
set(_p) set(_p)
set(_abs 0)
if (IS_ABSOLUTE "${_PATH}") if (IS_ABSOLUTE "${_PATH}")
set(_abs 1)
endif()
if ("${_PATH}" MATCHES "^\$<")
set(_abs 1)
endif()
if (_abs)
set(_p "${_PATH}") set(_p "${_PATH}")
else() else()
set(_p "${_RELPATH}/${_PATH}") set(_p "${_RELPATH}/${_PATH}")
endif() endif()
#if (EXISTS "${_p}") if ("${_p}" MATCHES ".*/$")
if ("${_p}" MATCHES ".*/")
string(LENGTH "${_p}" __sl) string(LENGTH "${_p}" __sl)
math(EXPR __sl ${__sl}-1) math(EXPR __sl ${__sl}-1)
string(SUBSTRING "${_p}" 0 ${__sl} _p) string(SUBSTRING "${_p}" 0 ${__sl} _p)
@@ -379,7 +403,6 @@ macro(__add_file_or_dir _DIR_VAR _FILE_VAR _PATH _RELPATH)
else() else()
list(APPEND ${_FILE_VAR} "${_p}") list(APPEND ${_FILE_VAR} "${_p}")
endif() endif()
#endif()
endmacro() endmacro()
set(__win_host 0) set(__win_host 0)
@@ -507,9 +530,9 @@ set(__macos_privacies
<key>NSVideoSubscriberAccountUsageDescription</key> <key>NSVideoSubscriberAccountUsageDescription</key>
<string>${__macos_privacy_text}</string>" <string>${__macos_privacy_text}</string>"
) )
#defaultConfig { set(__gradle_lang_start
# resConfigs "ru" " defaultConfig {
#} resConfigs ")
set(__gradle_sign set(__gradle_sign
" signingConfigs { " signingConfigs {
debug { debug {
@@ -544,17 +567,28 @@ macro(deploy_target _T)
set(_PLUG_FILES) set(_PLUG_FILES)
set(_FILE_DIRS) set(_FILE_DIRS)
set(_FILE_FILES) set(_FILE_FILES)
set(_LIBS_DIRS)
set(_LIBS_FILES)
set(_VERB) set(_VERB)
set(_WVERB 1> NUL) set(_WVERB 1> NUL)
set(_OPTIONS) set(_OPTIONS)
set(_ZIP_DMG 1)
set(_DEB_OPT 1)
set(_DEB_SERVICE 0)
set(_cur_arg) set(_cur_arg)
set(__args "DESTINATION;DEPLOY_DIR;RESOURCES;PLUGINS;FILES;OPTIONS;VERBOSE") set(__args "DESTINATION;DEPLOY_DIR;RESOURCES;PLUGINS;FILES;LIBS;OPTIONS;VERBOSE;DMG_NO_ZIP;DEB_USR_DIR;DEB_ADD_SERVICE")
foreach(_i ${ARGN}) foreach(_i ${ARGN})
if (_i IN_LIST __args) if (_i IN_LIST __args)
set(_cur_arg "${_i}") set(_cur_arg "${_i}")
if ("${_cur_arg}" STREQUAL "VERBOSE") if ("${_cur_arg}" STREQUAL "VERBOSE")
set(_VERB -v) set(_VERB -v)
set(_WVERB) set(_WVERB)
elseif("${_cur_arg}" STREQUAL "DMG_NO_ZIP")
set(_ZIP_DMG 0)
elseif("${_cur_arg}" STREQUAL "DEB_USR_DIR")
set(_DEB_OPT 0)
elseif("${_cur_arg}" STREQUAL "DEB_ADD_SERVICE")
set(_DEB_SERVICE 1)
endif() endif()
elseif ("${_cur_arg}" STREQUAL "DESTINATION") elseif ("${_cur_arg}" STREQUAL "DESTINATION")
set(_cur_arg) set(_cur_arg)
@@ -568,6 +602,8 @@ macro(deploy_target _T)
__add_file_or_dir(_PLUG_DIRS _PLUG_FILES "${_i}" "${_DEPLOY_DIR}") __add_file_or_dir(_PLUG_DIRS _PLUG_FILES "${_i}" "${_DEPLOY_DIR}")
elseif ("${_cur_arg}" STREQUAL "FILES") elseif ("${_cur_arg}" STREQUAL "FILES")
__add_file_or_dir(_FILE_DIRS _FILE_FILES "${_i}" "${_DEPLOY_DIR}") __add_file_or_dir(_FILE_DIRS _FILE_FILES "${_i}" "${_DEPLOY_DIR}")
elseif ("${_cur_arg}" STREQUAL "LIBS")
__add_file_or_dir(_LIBS_DIRS _LIBS_FILES "${_i}" "${_DEPLOY_DIR}")
elseif ("${_cur_arg}" STREQUAL "OPTIONS") elseif ("${_cur_arg}" STREQUAL "OPTIONS")
list(APPEND _OPTIONS "${_i}") list(APPEND _OPTIONS "${_i}")
endif() endif()
@@ -581,21 +617,47 @@ macro(deploy_target _T)
set(_DEP_LIBS) set(_DEP_LIBS)
set(_add_search_path) set(_add_search_path)
set(_added_) set(_added_)
set(_ADD_DEPS ${_PLUG_DIRS} ${_PLUG_FILES} ${_FILE_DIRS} ${_FILE_FILES}) set(_ADD_DEPS ${_PLUG_DIRS} ${_PLUG_FILES} ${_FILE_DIRS} ${_FILE_FILES} ${_LIBS_DIRS} ${_LIBS_FILES})
__gather_deps(${_T} _add_search_path _DEP_LIBS _DEP_LIBS_CS _added_) __gather_deps(${_T} _add_search_path _DEP_LIBS _DEP_LIBS_CS _added_)
foreach (_L ${DEPLOY_ADD_LIBPATH}) foreach (_L ${DEPLOY_ADD_LIBPATH})
set(_add_search_path "${_add_search_path}${_dt_delim}${_L}") set(_add_search_path "${_add_search_path}${_dt_delim}${_L}")
endforeach() endforeach()
#set(_add_search_path "${_add_search_path}")
#message("app depend ${_T} libpath ${_add_search_path}") #message("app depend ${_T} libpath ${_add_search_path}")
set(_CMD_) set(_CMD_)
set(_has_deploy 0) set(_deployed)
if ("x${CMAKE_SYSTEM_NAME}" STREQUAL "xLinux") if ("x${CMAKE_SYSTEM_NAME}" STREQUAL "xLinux")
if (NOT CMAKE_LDD) set(_os_id "")
find_program(CMAKE_LDD ldd) set(_os_ver "")
set(_paths "/usr/lib" "/etc")
if (CMAKE_CROSSCOMPILING)
set(_paths "${CMAKE_PREFIX_PATH}/lib" "${CMAKE_PREFIX_PATH}/../etc")
endif()
find_file(_release_file NAMES os-release lsb-release PATHS ${_paths} NO_DEFAULT_PATH)
if (NOT "x${_release_file}" STREQUAL "x")
file(STRINGS "${_release_file}" _lines)
foreach(_l ${_lines})
if ("${_l}" MATCHES "VERSION_ID=.*")
string(SUBSTRING "${_l}" 11 -1 _os_ver)
string(REPLACE "\"" "" _os_ver "${_os_ver}")
#message("VERSION_ID ${_os_ver}")
elseif ("${_l}" MATCHES "ID=.*")
string(SUBSTRING "${_l}" 3 -1 _os_id)
string(REPLACE "\"" "" _os_id "${_os_id}")
#message("ID ${_os_id}")
endif()
endforeach()
endif()
set(_build "${${_T}_VERSION_BUILD}")
if (NOT "x${_build}" STREQUAL "x")
set(_build "-${_build}")
endif()
string(TOLOWER "${_os_id}${_os_ver}" _TARGET_OS)
if ("x${_TARGET_OS}" STREQUAL "x")
set(_TARGET_OS "linux")
endif() endif()
string(REPLACE "_" "-" _DEBNAME "${_T}") string(REPLACE "_" "-" _DEBNAME "${_T}")
string(REPLACE "_" "-" _DEBVERSION "${${_T}_VERSION}") string(REPLACE "_" "-" _DEBVERSION "${${_T}_VERSION}${_build}+${_TARGET_OS}")
string(TOLOWER "${_DEBNAME}" _DEBNAME)
set(_DEB_ARCH) set(_DEB_ARCH)
if("_${MY_ARCH}" STREQUAL "_arm64") if("_${MY_ARCH}" STREQUAL "_arm64")
set(_DEB_ARCH "arm64") set(_DEB_ARCH "arm64")
@@ -618,58 +680,161 @@ macro(deploy_target _T)
set(_C_echo ">>" "${_AGD}/DEBIAN/control") set(_C_echo ">>" "${_AGD}/DEBIAN/control")
set(_D_echof ">" "${_AGD}/usr/share/applications/${_DEBNAME}.desktop") set(_D_echof ">" "${_AGD}/usr/share/applications/${_DEBNAME}.desktop")
set(_D_echo ">>" "${_AGD}/usr/share/applications/${_DEBNAME}.desktop") set(_D_echo ">>" "${_AGD}/usr/share/applications/${_DEBNAME}.desktop")
__make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}/usr/share/${${_T}_COMPANY}/${_T}") set(_bin_path "${_AGD}/usr/bin")
__make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}/usr/lib/${${_T}_COMPANY}/${_T}") set(_lib_path "${_AGD}/usr/lib")
__make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}/usr/bin") set(_pli_path "${_AGD}/usr/lib/${${_T}_COMPANY}/${_T}")
set(_res_path "${_AGD}/usr/share/${${_T}_COMPANY}/${_T}")
set(_ico_path "${_AGD}/usr/share/pixmaps")
set(_app_bin_path "/usr/bin")
set(_app_ico_path "/usr/share/pixmaps")
if(_DEB_OPT)
set(_bin_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}")
set(_lib_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}/lib")
set(_pli_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}")
set(_res_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}")
set(_ico_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}/pixmaps")
set(_app_bin_path "/opt/${${_T}_COMPANY}/${_T}")
set(_app_ico_path "/opt/${${_T}_COMPANY}/${_T}/pixmaps")
endif()
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_bin_path}")
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_lib_path}")
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_pli_path}")
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_res_path}")
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_ico_path}")
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_AGD}/usr/share/applications")
__make_copy(_CMD_ _FILE_DIRS _FILE_FILES ${_bin_path})
__make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES ${_pli_path})
__make_copy(_CMD_ _RES_DIRS _RES_FILES ${_res_path})
__make_copy(_CMD_ _LIBS_DIRS _LIBS_FILES ${_lib_path})
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_DEPLOY_DIR}/${_T}" "${_bin_path}/")
if (_DEP_LIBS) if (_DEP_LIBS)
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f ${_DEP_LIBS} ${_AGD}/usr/lib) set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_DEP_LIBS}" "${_lib_path}/")
endif() endif()
if (_ICON_NAME) if (_ICON_NAME)
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f ${_ICON_FN} ${_AGD}/usr/share/pixmaps) set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_ICON_FN}" "${_ico_path}/")
endif() endif()
if(_DEB_OPT)
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_AGD}/usr/bin")
set(_CMD_ ${_CMD_} COMMAND ln -srf ${_VERB} "${_bin_path}/${_T}" "${_AGD}/usr/bin/${_T}")
endif()
file(GLOB _files "${CMAKE_CURRENT_SOURCE_DIR}/debian/DEBIAN/*")
foreach (_f ${_files})
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_f}" "${_AGD}/DEBIAN/")
endforeach()
file(GLOB _files "${_AGD}/DEBIAN/p*inst" "${_AGD}/DEBIAN/p*rm" "${_AGD}/DEBIAN/config")
foreach (_f ${_files})
set(_CMD_ ${_CMD_} COMMAND chmod 0755 ${_VERB} "${_f}")
endforeach()
if (NOT CMAKE_LDD)
find_program(CMAKE_LDD ldd)
endif()
set(_dt_opts -l "${CMAKE_LDD}")
if (CMAKE_CROSSCOMPILING)
set(_dt_searchdirs "${CMAKE_PREFIX_PATH}/lib")
if (NOT "x${CMAKE_LIBRARY_ARCHITECTURE}" STREQUAL "x")
set(_dt_searchdirs "${_dt_searchdirs}${_dt_delim}${CMAKE_PREFIX_PATH}/lib/${CMAKE_LIBRARY_ARCHITECTURE}")
set(_dt_searchdirs "${_dt_searchdirs}${_dt_delim}${CMAKE_PREFIX_PATH}/../lib/${CMAKE_LIBRARY_ARCHITECTURE}")
endif()
set(_dt_opts -L "${CMAKE_READELF}" --dpkg-workdir "${CMAKE_DPKG_WORKDIR}" -s "${_dt_searchdirs}")
endif()
set(_deb_name "${_TV}_${_TARGET_OS}_${_DEB_ARCH}.deb")
#message("VER = \"${_DEBVERSION}\"")
#message("DEB = \"${_deb_name}\"")
list(APPEND _CMD_ COMMAND echo "Package: ${_DEBNAME}" ${_C_echof})
list(APPEND _CMD_ COMMAND echo "Version: ${_DEBVERSION}" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Architecture: ${_DEB_ARCH}" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Maintainer: ${${_T}_COMPANY} <>" ${_C_echo})
list(APPEND _CMD_ COMMAND ${PIP_DEPLOY_TOOL} ${_OPTIONS} --prefix "Depends: " --dependencies ${_dt_opts} -a "${_DEP_LIBS_CS}" -o "${_lib_path}" ${_DEPLOY_DIR}/${_T} ${_ADD_DEPS} ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Conflicts:" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Replaces:" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Section: misc" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Priority: optional" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Description: ${${_T}_INFO}" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "[Desktop Entry]" ${_D_echof})
list(APPEND _CMD_ COMMAND echo "Encoding=UTF-8" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Type=Application" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Name=${${_T}_LABEL}" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "GenericName=${${_T}_LABEL}" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Comment=${${_T}_INFO}" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Exec=${_app_bin_path}/${_T}" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Icon=${_app_ico_path}/${_ICON_NAME}" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Terminal=false" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "StartupNotify=true" ${_D_echo})
list(APPEND _CMD_ COMMAND echo "Categories=Utility;" ${_D_echo})
add_custom_target(deploy_${_T} add_custom_target(deploy_${_T}
# gather deb dir # gather deb dir
COMMAND mkdir ${_VERB} -p ${_AGD}/DEBIAN COMMAND rm -rf ${_VERB} "${_AGD}"
COMMAND mkdir ${_VERB} -p ${_AGD}/usr/bin COMMAND mkdir ${_VERB} -p "${_AGD}/DEBIAN"
COMMAND mkdir ${_VERB} -p ${_AGD}/usr/lib
COMMAND mkdir ${_VERB} -p ${_AGD}/usr/share/pixmaps
COMMAND mkdir ${_VERB} -p ${_AGD}/usr/share/applications
COMMAND cp ${_VERB} -f ${_DEPLOY_DIR}/${_T} ${_AGD}/usr/bin
${_CMD_} ${_CMD_}
COMMAND echo "Package: ${_DEBNAME}" ${_C_echof}
COMMAND echo "Version: ${_DEBVERSION}" ${_C_echo}
COMMAND echo "Architecture: ${_DEB_ARCH}" ${_C_echo}
COMMAND echo "Maintainer: ${${_T}_COMPANY} <>" ${_C_echo}
COMMAND deploy_tool ${_OPTIONS} --prefix "Depends: " --dependencies -l ${CMAKE_LDD} -a "${_DEP_LIBS_CS}" -o "${_AGD}/usr/lib" ${_DEPLOY_DIR}/${_T} ${_ADD_DEPS} ${_C_echo}
COMMAND echo "Conflicts:" ${_C_echo}
COMMAND echo "Replaces:" ${_C_echo}
COMMAND echo "Section: misc" ${_C_echo}
COMMAND echo "Priority: optional" ${_C_echo}
COMMAND echo "Description: ${${_T}_INFO}" ${_C_echo}
COMMAND echo "[Desktop Entry]" ${_D_echof}
COMMAND echo "Encoding=UTF-8" ${_D_echo}
COMMAND echo "Type=Application" ${_D_echo}
COMMAND echo "Name=${${_T}_LABEL}" ${_D_echo}
COMMAND echo "GenericName=${${_T}_LABEL}" ${_D_echo}
COMMAND echo "Comment=${${_T}_INFO}" ${_D_echo}
COMMAND echo "Exec=/usr/bin/${_T}" ${_D_echo}
COMMAND echo "Icon=/usr/share/pixmaps/${_ICON_NAME}" ${_D_echo}
COMMAND echo "Terminal=false" ${_D_echo}
COMMAND echo "StartupNotify=true" ${_D_echo}
#COMMAND echo "X-KDE-StartupNotify=true" ${_D_echo}
COMMAND echo "Categories=Utility;" ${_D_echo}
#COMMAND -l "${CMAKE_LDD}" -P xcb -q ${Qt5_ROOT} -s "\"${CMAKE_PREFIX_PATH}/lib;${_add_search_path}\"" -o ${_AGD}/usr/lib -p ${_AGD}/usr/ ${_AGD}/Contents/MacOS/${_T}
# generate deb # generate deb
COMMAND cd ${_AGD} "&&" md5deep -rl usr ">" DEBIAN/md5sums COMMAND cd ${_AGD} "&&" md5deep -rl opt usr ">" DEBIAN/md5sums
COMMAND mkdir ${_VERB} -p ${_DESTINATION} COMMAND mkdir ${_VERB} -p ${_DESTINATION}
COMMAND dpkg-deb -b ${_AGD} ${_DESTINATION}/${_TV}_${_DEB_ARCH}.deb COMMAND dpkg-deb -Z gzip -b ${_AGD} ${_DESTINATION}/${_deb_name}
VERBATIM VERBATIM
COMMENT "Generating ${_TV}_${_DEB_ARCH}.deb" COMMENT "Generating ${_deb_name}"
) )
set(_has_deploy 1) set(_deployed "deploy_${_T}")
if (_DEB_SERVICE)
set(_CMD_)
set(_DEB "${_TV}-service_deb_${_DEB_ARCH}")
set(_AGD "${_DEPLOY_DIR}/${_DEB}")
set(_C_echof ">" "${_AGD}/DEBIAN/control")
set(_C_echo ">>" "${_AGD}/DEBIAN/control")
set(_opt_path "${_AGD}/opt/${${_T}_COMPANY}/${_T}")
set(_CMD_ ${_CMD_} COMMAND mkdir ${_VERB} -p "${_opt_path}")
file(GLOB _files "${CMAKE_CURRENT_SOURCE_DIR}/debian-service/*.service")
foreach (_f ${_files})
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_f}" "${_opt_path}/")
endforeach()
set(__deb_dir "${CMAKE_CURRENT_SOURCE_DIR}/debian-service/DEBIAN")
file(GLOB _files "${__deb_dir}/*")
foreach (_f ${_files})
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f "${_f}" "${_AGD}/DEBIAN/")
endforeach()
file(GLOB _files RELATIVE "${__deb_dir}" "${__deb_dir}/p*inst" "${__deb_dir}/p*rm" "${__deb_dir}/config")
foreach (_f ${_files})
set(_CMD_ ${_CMD_} COMMAND chmod 0755 ${_VERB} "${_AGD}/DEBIAN/${_f}")
endforeach()
set(_deb_name "${_TV}-service_${_TARGET_OS}_${_DEB_ARCH}.deb")
#message("VER = \"${_DEBVERSION}\"")
#message("DEB = \"${_deb_name}\"")
list(APPEND _CMD_ COMMAND echo "Package: ${_DEBNAME}-service" ${_C_echof})
list(APPEND _CMD_ COMMAND echo "Version: ${_DEBVERSION}" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Architecture: ${_DEB_ARCH}" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Maintainer: ${${_T}_COMPANY} <>" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Depends: ${_DEBNAME} (>= ${_DEBVERSION})" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Conflicts:" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Replaces:" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Section: misc" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Priority: optional" ${_C_echo})
list(APPEND _CMD_ COMMAND echo "Description: ${${_T}_LABEL} service" ${_C_echo})
add_custom_target(deploy_${_T}-service
# gather deb dir
COMMAND rm -rf ${_VERB} "${_AGD}"
COMMAND mkdir ${_VERB} -p "${_AGD}/DEBIAN"
${_CMD_}
# generate deb
COMMAND mkdir ${_VERB} -p ${_DESTINATION}
COMMAND dpkg-deb -Z gzip -b ${_AGD} ${_DESTINATION}/${_deb_name}
VERBATIM
COMMENT "Generating ${_deb_name}"
)
list(APPEND _deployed "deploy_${_T}-service")
endif()
elseif(WIN32) elseif(WIN32)
if (NOT CMAKE_OBJDUMP) if (NOT CMAKE_OBJDUMP)
find_program(CMAKE_OBJDUMP objdump) find_program(CMAKE_OBJDUMP objdump)
@@ -686,16 +851,18 @@ macro(deploy_target _T)
__make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}") __make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}")
__make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}") __make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}")
__make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}") __make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}")
__make_copy(_CMD_ _LIBS_DIRS _LIBS_FILES "${_AGD}")
set(_zip_name "${_TV}_windows_${MY_ARCH}.zip")
add_custom_target(deploy_${_T} add_custom_target(deploy_${_T}
# gather dir # gather dir
${_CMD_} ${_CMD_}
COMMAND deploy_tool ${_VERB} ${_OPTIONS} -W "\"${CMAKE_OBJDUMP}\"" -P windows,minimal -S windows -q "\"${Qt5_ROOT}\"" -s "\"${CMAKE_PREFIX_PATH}/bin${_dt_delim}${MINGW_BIN}${_add_search_path}\"" -o ${_AGD} -p ${_AGD} "\"${_AGD}${_T}.exe\"" ${_ADD_DEPS} COMMAND ${PIP_DEPLOY_TOOL} ${_VERB} ${_OPTIONS} -W "\"${CMAKE_OBJDUMP}\"" -P windows,minimal -S windows -q "\"${Qt5_ROOT}\"" -s "\"${CMAKE_PREFIX_PATH}/bin${_dt_delim}${MINGW_BIN}${_add_search_path}\"" -o ${_AGD} -p ${_AGD} "\"${_AGD}${_T}.exe\"" ${_ADD_DEPS}
# zip # zip
COMMAND cd "\"${_DEPLOY_DIR}\"" "&&" zip -q -r "\"${_DESTINATION}/${_TV}.zip\"" "\"${_TV}_win_${MY_ARCH}\"" COMMAND cd "\"${_DEPLOY_DIR}\"" "&&" zip -q -r "\"${_DESTINATION}/${_zip_name}\"" "\"${_TV}_win_${MY_ARCH}\""
COMMENT "Generating ${_TV}.zip" COMMENT "Generating ${_zip_name}"
) )
set(_has_deploy 1) set(_deployed "deploy_${_T}")
elseif (APPLE) elseif (APPLE)
set(MACOSX_BUNDLE_GUI_IDENTIFIER "${${_T}_FULLNAME}") set(MACOSX_BUNDLE_GUI_IDENTIFIER "${${_T}_FULLNAME}")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${${_T}_VERSION}") set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${${_T}_VERSION}")
@@ -714,6 +881,7 @@ macro(deploy_target _T)
__make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}/Contents/Resources") __make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}/Contents/Resources")
__make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}/Contents/PlugIns") __make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}/Contents/PlugIns")
__make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}/Contents/MacOS") __make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}/Contents/MacOS")
__make_copy(_CMD_ _LIBS_DIRS _LIBS_FILES "${_AGD}/Contents/Frameworks")
if (_ICON_NAME) if (_ICON_NAME)
set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f ${_ICON_FN} ${_AGD}/Contents/Resources) set(_CMD_ ${_CMD_} COMMAND cp ${_VERB} -f ${_ICON_FN} ${_AGD}/Contents/Resources)
endif() endif()
@@ -723,14 +891,18 @@ macro(deploy_target _T)
if (NOT CMAKE_PREFIX_PATH) if (NOT CMAKE_PREFIX_PATH)
set(CMAKE_PREFIX_PATH "/usr/local") set(CMAKE_PREFIX_PATH "/usr/local")
endif() endif()
set(_cmd_gen_dmg COMMAND genisoimage -quiet -V "${MACOSX_BUNDLE_BUNDLE_NAME}" -D -R -apple -no-pad -o ${_DESTINATION}/${_TV}.dmg ${_DMG}) set(_dmg_name "${_TV}_macosx_x64.dmg")
#set(_cmd_int) set(_cmd_gen_dmg COMMAND genisoimage -quiet -V "${MACOSX_BUNDLE_BUNDLE_NAME}" -D -R -apple -no-pad -o ${_DESTINATION}/${_dmg_name} ${_DMG})
if (__mac_host) if (__mac_host)
set(_cmd_gen_dmg COMMAND hdiutil create ${_DESTINATION}/${_TV}.dmg -ov -volname "${MACOSX_BUNDLE_BUNDLE_NAME}" -fs HFS+ -srcfolder ${_DMG}) set(_cmd_gen_dmg COMMAND hdiutil create ${_DESTINATION}/${_dmg_name} -ov -volname "${MACOSX_BUNDLE_BUNDLE_NAME}" -fs HFS+ -srcfolder ${_DMG})
#set(_rpathes "@executable_path/../Frameworks" "@executable_path/lib" "@loader_path/../lib") endif()
#foreach (_r ${_rpathes}) if (_ZIP_DMG)
# set(_cmd_int ${_cmd_int} COMMAND install_name_tool -add_rpath "${_r}" \"${_AGD}/Contents/MacOS/${_T}\") set(_cmd_gen_dmg ${_cmd_gen_dmg} COMMAND zip -q -r "\"${_DESTINATION}/${_dmg_name}.zip\"" "\"${_DESTINATION}/${_dmg_name}\"")
#endforeach() set(_cmd_gen_dmg ${_cmd_gen_dmg} COMMAND rm "\"${_DESTINATION}/${_dmg_name}\"")
endif()
set(_comment "Generating ${_dmg_name}")
if (_ZIP_DMG)
set(_comment "${_comment}.zip")
endif() endif()
add_custom_target(deploy_${_T} add_custom_target(deploy_${_T}
# gather .app dir # gather .app dir
@@ -738,10 +910,7 @@ macro(deploy_target _T)
COMMAND mkdir ${_VERB} -p ${_AGD}/Contents/Frameworks COMMAND mkdir ${_VERB} -p ${_AGD}/Contents/Frameworks
COMMAND mkdir ${_VERB} -p ${_DESTINATION} COMMAND mkdir ${_VERB} -p ${_DESTINATION}
${_CMD_} ${_CMD_}
#COMMAND cp ${_ICON_FN} ${_AGD}/Contents/Resources COMMAND ${PIP_DEPLOY_TOOL} ${_VERB} ${_OPTIONS} -M "${CMAKE_OTOOL}" -P cocoa,minimal -S mac -q ${Qt5_ROOT} -s "\"${CMAKE_PREFIX_PATH}/lib${_add_search_path}\"" -o ${_AGD}/Contents/Frameworks -p ${_AGD}/Contents/PlugIns ${_AGD}/Contents/MacOS/${_T} ${_ADD_DEPS}
#COMMAND cp -r ${_DEPLOY_DIR}/lang ${_AGD}/Contents/Resources
COMMAND deploy_tool ${_VERB} ${_OPTIONS} -M "${CMAKE_OTOOL}" -P cocoa,minimal -S mac -q ${Qt5_ROOT} -s "\"${CMAKE_PREFIX_PATH}/lib${_add_search_path}\"" -o ${_AGD}/Contents/Frameworks -p ${_AGD}/Contents/PlugIns ${_AGD}/Contents/MacOS/${_T} ${_ADD_DEPS}
#${_cmd_int}
# prepare dmg dir # prepare dmg dir
COMMAND rm -rf ${_DMG} COMMAND rm -rf ${_DMG}
COMMAND mkdir ${_VERB} -p ${_DMG} COMMAND mkdir ${_VERB} -p ${_DMG}
@@ -749,9 +918,9 @@ macro(deploy_target _T)
COMMAND ln ${_VERB} -s /Applications ${_DMG} COMMAND ln ${_VERB} -s /Applications ${_DMG}
# generate dmg # generate dmg
${_cmd_gen_dmg} ${_cmd_gen_dmg}
COMMENT "Generating ${_TV}.dmg" COMMENT "${_comment}"
) )
set(_has_deploy 1) set(_deployed "deploy_${_T}")
elseif (DEFINED ANDROID_PLATFORM) elseif (DEFINED ANDROID_PLATFORM)
set(_res_files) set(_res_files)
set(_res_files "${_res_files}\n <qresource prefix=\"/\">") set(_res_files "${_res_files}\n <qresource prefix=\"/\">")
@@ -772,17 +941,17 @@ macro(deploy_target _T)
endforeach() endforeach()
set(_res_qrc "${CMAKE_CURRENT_BINARY_DIR}/android_res.qrc") set(_res_qrc "${CMAKE_CURRENT_BINARY_DIR}/android_res.qrc")
file(WRITE "${_res_qrc}" "<RCC>${_res_files}\n</RCC>") file(WRITE "${_res_qrc}" "<RCC>${_res_files}\n</RCC>")
#__make_copy(_CMD_ _RES_DIRS _RES_FILES "${_AGD}/res")
#__make_copy(_CMD_ _FILE_DIRS _FILE_FILES "${_AGD}/Contents/MacOS")
set(_AT ${_T}_lib) set(_AT ${_T}_lib)
set(_ATA ${_AT}_${ANDROID_ABI}) set(_ATA ${_AT}_${ANDROID_ABI})
get_target_property(_sources ${_T} SOURCES) get_target_property(_sources ${_T} SOURCES)
get_target_property(_libs ${_T} LINK_LIBRARIES) get_target_property(_libs ${_T} LINK_LIBRARIES)
get_target_property(_incs ${_T} INCLUDE_DIRECTORIES) get_target_property(_incs ${_T} INCLUDE_DIRECTORIES)
get_target_property(_defs ${_T} COMPILE_DEFINITIONS)
qt5_add_resources(_res_out "${_res_qrc}") qt5_add_resources(_res_out "${_res_qrc}")
add_library(${_ATA} SHARED ${_sources} ${_res_out}) add_library(${_ATA} SHARED ${_sources} ${_res_out})
target_link_libraries(${_ATA} ${_libs}) target_link_libraries(${_ATA} ${_libs})
target_include_directories(${_ATA} PRIVATE ${_incs}) target_include_directories(${_ATA} PRIVATE ${_incs})
target_compile_definitions(${_ATA} PRIVATE ${_defs})
set_target_properties(${_T} PROPERTIES EXCLUDE_FROM_ALL 1) set_target_properties(${_T} PROPERTIES EXCLUDE_FROM_ALL 1)
#message("create new target ${_ATA} ${_sources} ${_libs}") #message("create new target ${_ATA} ${_sources} ${_libs}")
set(_AGD "${_DEPLOY_DIR}/${_T}.android") set(_AGD "${_DEPLOY_DIR}/${_T}.android")
@@ -797,9 +966,7 @@ macro(deploy_target _T)
set(_file "${Qt5_ROOT}/src/3rdparty/gradle/gradlew" set(_file "${Qt5_ROOT}/src/3rdparty/gradle/gradlew"
"${Qt5_ROOT}/src/3rdparty/gradle/gradlew.bat") "${Qt5_ROOT}/src/3rdparty/gradle/gradlew.bat")
__make_copy(_CMD_ _dir _file "${_AGD}") __make_copy(_CMD_ _dir _file "${_AGD}")
#__make_copy(_CMD_ _PLUG_DIRS _PLUG_FILES "${_AGD}/")
#message("bindir = ${CMAKE_CURRENT_SOURCE_DIR}") #message("bindir = ${CMAKE_CURRENT_SOURCE_DIR}")
#get_target_property(_LL ${_T} )
set(SDK_ROOT "$ENV{ANDROID_SDK_ROOT}") set(SDK_ROOT "$ENV{ANDROID_SDK_ROOT}")
if("x${SDK_ROOT}" STREQUAL "x") if("x${SDK_ROOT}" STREQUAL "x")
set(SDK_ROOT "$ENV{ANDROID_HOME}") set(SDK_ROOT "$ENV{ANDROID_HOME}")
@@ -827,7 +994,7 @@ macro(deploy_target _T)
string(REPLACE "${ANDROID_SYSROOT_${ANDROID_ABI}}" "${ANDROID_SYSROOT_${_a}}" _lib_${_a} "${_lib_}") string(REPLACE "${ANDROID_SYSROOT_${ANDROID_ABI}}" "${ANDROID_SYSROOT_${_a}}" _lib_${_a} "${_lib_}")
#message("search = ${_a_prefix}/lib") #message("search = ${_a_prefix}/lib")
__make_copy(_CMD_ _empty _lib_${_a} "${_AGD}/libs/${_a}") __make_copy(_CMD_ _empty _lib_${_a} "${_AGD}/libs/${_a}")
set(_CMD_ ${_CMD_} COMMAND deploy_tool ${_VERB} ${_OPTIONS} -W "\"${CMAKE_OBJDUMP}\"" -s "${_a_prefix}/lib${_dt_delim}${Qt5_ROOT}/lib${_add_search_path}" -o "\"${_AGD}/libs/${_a}\"" --ignore "\"c${_dt_delim}m${_dt_delim}z${_dt_delim}dl${_dt_delim}log\"" "\"${_AGD}/libs/${_a}/lib${_AT}_${_a}.so\"" ${_ADD_DEPS}) set(_CMD_ ${_CMD_} COMMAND ${PIP_DEPLOY_TOOL} ${_VERB} ${_OPTIONS} -W "\"${CMAKE_OBJDUMP}\"" -s "${_a_prefix}/lib${_dt_delim}${Qt5_ROOT}/lib${_add_search_path}" -o "\"${_AGD}/libs/${_a}\"" --ignore "\"c${_dt_delim}m${_dt_delim}z${_dt_delim}dl${_dt_delim}log\"" "\"${_AGD}/libs/${_a}/lib${_AT}_${_a}.so\"" ${_ADD_DEPS})
#message("c++_${_a} -> ${_lib_${_a}}") #message("c++_${_a} -> ${_lib_${_a}}")
endif() endif()
endforeach() endforeach()
@@ -846,6 +1013,11 @@ macro(deploy_target _T)
if (NOT IS_ABSOLUTE "${ANDROID_STORE_FILE}") if (NOT IS_ABSOLUTE "${ANDROID_STORE_FILE}")
set(ANDROID_STORE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_STORE_FILE}") set(ANDROID_STORE_FILE "${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_STORE_FILE}")
endif() endif()
if (${_T}_ANDROID_NEW_LOADER)
set(ANDROID_NEW_LOADER "true")
else()
set(ANDROID_NEW_LOADER "false")
endif()
set(__ANDROID_DEBUG_KEYSTORE__ "${_modules_dir}/android_debug.keystore") set(__ANDROID_DEBUG_KEYSTORE__ "${_modules_dir}/android_debug.keystore")
set(QT_DIR ${Qt5_ROOT}) set(QT_DIR ${Qt5_ROOT})
set(_out_json "${CMAKE_CURRENT_BINARY_DIR}/${_T}_android_deployment_settings.json") set(_out_json "${CMAKE_CURRENT_BINARY_DIR}/${_T}_android_deployment_settings.json")
@@ -856,33 +1028,41 @@ macro(deploy_target _T)
foreach (_d ${ANDROID_GRADLE_DEPENDENCIES}) foreach (_d ${ANDROID_GRADLE_DEPENDENCIES})
set(_depstr "${_depstr}\n ${_d}") set(_depstr "${_depstr}\n ${_d}")
endforeach() endforeach()
set(__gradle_lang)
foreach (_l ${${_T}_LANG})
if (NOT "x${__gradle_lang}" STREQUAL "x")
set(__gradle_lang "${__gradle_lang}, ")
endif()
set(__gradle_lang "${__gradle_lang}\"${_l}\"")
endforeach()
if ("x${__gradle_lang}" STREQUAL "x")
set(__gradle_lang "\"en\"")
endif()
file(READ "${Qt5_ROOT}/src/android/templates/build.gradle" _file) file(READ "${Qt5_ROOT}/src/android/templates/build.gradle" _file)
string(REPLACE "\ndependencies {" "\ndependencies {${_depstr}" _file "${_file}") string(REPLACE "\ndependencies {" "\ndependencies {${_depstr}" _file "${_file}")
string(REPLACE "\nandroid {" "\nandroid {\n${__gradle_sign}" _file "${_file}") string(REPLACE "\nandroid {" "\nandroid {\n${__gradle_sign}\n${__gradle_lang_start}${__gradle_lang}\n\t}\n" _file "${_file}")
string(REPLACE "['resources']" "['res']" _file "${_file}") string(REPLACE "['resources']" "['res']" _file "${_file}")
file(WRITE "${_AGD}/build.gradle" "${_file}") file(WRITE "${_AGD}/build.gradle" "${_file}")
set(_gradle_home) set(_gradle_home)
if (NOT __win_host) if (NOT __win_host)
set(_gradle_home "-g" "${CMAKE_BINARY_DIR}") set(_gradle_home "-g" "${CMAKE_BINARY_DIR}")
endif() endif()
#set(_CMD_ ${_CMD_} COMMAND "${SDK_ROOT}/tools/android" update project --path "\"${_AGD}\"" --target android-${ANDROID_TARGET_SDK} --name QtApp)
set(_CMD_ ${_CMD_} COMMAND "${Qt5_BIN}/androiddeployqt" --aux-mode --android-platform ${ANDROID_PLATFORM} --output "\"${_AGD}\"" --input "\"${_out_json}\"") set(_CMD_ ${_CMD_} COMMAND "${Qt5_BIN}/androiddeployqt" --aux-mode --android-platform ${ANDROID_PLATFORM} --output "\"${_AGD}\"" --input "\"${_out_json}\"")
set(_CMD_ ${_CMD_} COMMAND "${_AGD}/gradlew" ${_gradle_home} --no-daemon -p "\"${_AGD}\"" assembleDebug) set(_CMD_ ${_CMD_} COMMAND "${_AGD}/gradlew" ${_gradle_home} --no-daemon -p "\"${_AGD}\"" assembleDebug)
set(_CMD_ ${_CMD_} COMMAND "${_AGD}/gradlew" ${_gradle_home} --no-daemon -p "\"${_AGD}\"" bundleRelease) set(_CMD_ ${_CMD_} COMMAND "${_AGD}/gradlew" ${_gradle_home} --no-daemon -p "\"${_AGD}\"" bundleRelease)
set(_dir) set(_base_name "${_TV}_android_all")
set(_file "${_AGD}/build/outputs/apk/debug/${_T}.android-debug.apk") set(_CMD_ ${_CMD_} COMMAND "${CMAKE_COMMAND}" -E copy "${_AGD}/build/outputs/apk/debug/${_T}.android-debug.apk" "${_DESTINATION}/${_base_name}.apk")
if (ANDROID_STORE_FILE) if (ANDROID_STORE_FILE)
list(APPEND _file "${_AGD}/build/outputs/bundle/release/${_T}.android-release.aab") set(_CMD_ ${_CMD_} COMMAND "${CMAKE_COMMAND}" -E copy "${_AGD}/build/outputs/bundle/release/${_T}.android-release.aab" "${_DESTINATION}/${_base_name}.aab")
endif() endif()
__make_copy(_CMD_ _dir _file "${_DESTINATION}")
add_custom_target(deploy_${_T} add_custom_target(deploy_${_T}
# gather .app dir # gather .app dir
${_CMD_} ${_CMD_}
COMMENT "Generating ${_TV}.apk/aab" COMMENT "Generating ${_base_name}.apk/aab"
) )
set(_has_deploy 1) set(_deployed "deploy_${_T}")
endif()
if (_has_deploy)
add_dependencies(deploy deploy_${_T})
endif() endif()
foreach (_d ${_deployed})
add_dependencies(deploy ${_d})
endforeach()
endmacro() endmacro()

View File

@@ -12,7 +12,6 @@ if(${MINGW})
PATH_SUFFIXES PATH_SUFFIXES
include) include)
#message(STATUS "Find MinGW = ${MINGW_INCLUDE}") #message(STATUS "Find MinGW = ${MINGW_INCLUDE}")
#if(NOT ${MINGW_INCLUDE}) MINGW_INCLUDE = ${MINGW_DIR}/include
find_library(MINGW_LIB m HINTS ${MINGW_BIN}/../lib ${MINGW_INCLUDE}/../lib) find_library(MINGW_LIB m HINTS ${MINGW_BIN}/../lib ${MINGW_INCLUDE}/../lib)
get_filename_component(MINGW_LIB ${MINGW_LIB} PATH) get_filename_component(MINGW_LIB ${MINGW_LIB} PATH)
if (NOT _MGW_MSG) if (NOT _MGW_MSG)

View File

@@ -3,12 +3,14 @@
Also create imported targets: Also create imported targets:
* PIP - main library * PIP - main library
* PIP::USB * PIP::USB
* PIP::Console
* PIP::Crypt * PIP::Crypt
* PIP::FFTW
* PIP::Compress * PIP::Compress
* PIP::FFTW
* PIP::OpenCL
* PIP::IOUtils * PIP::IOUtils
* PIP::Concurrent
* PIP::Cloud * PIP::Cloud
* PIP::Lua
These targets include directories and depends on These targets include directories and depends on
main library main library
@@ -16,7 +18,6 @@ main library
]] ]]
cmake_policy(SET CMP0011 NEW) # don`t affect includer policies cmake_policy(SET CMP0011 NEW) # don`t affect includer policies
#set(_PIP_MODULES pip pip_usb pip_crypt pip_fftw)
if(WIN32) if(WIN32)
find_package(MinGW REQUIRED) find_package(MinGW REQUIRED)
endif() endif()
@@ -33,10 +34,6 @@ endif()
if(CMAKE_CROSSCOMPILING) if(CMAKE_CROSSCOMPILING)
list(APPEND _PIP_INCDIR "${CMAKE_PREFIX_PATH}/include/pip") list(APPEND _PIP_INCDIR "${CMAKE_PREFIX_PATH}/include/pip")
list(APPEND _PIP_LIBDIR "${CMAKE_PREFIX_PATH}/lib") list(APPEND _PIP_LIBDIR "${CMAKE_PREFIX_PATH}/lib")
#if (DEFINED ANDROID_PLATFORM)
# list(APPEND _PIP_INCDIR ${CMAKE_PREFIX_PATH}/include/pip)
# list(APPEND _PIP_LIBDIR ${CMAKE_PREFIX_PATH}/lib)
#endif()
else() else()
if(NOT WIN32) if(NOT WIN32)
list(APPEND _PIP_INCDIR "/usr/include/pip" "/usr/local/include/pip") list(APPEND _PIP_INCDIR "/usr/include/pip" "/usr/local/include/pip")
@@ -60,26 +57,30 @@ else()
endif() endif()
list(APPEND _PIP_BINDIR "${PIP_DIR}/bin") list(APPEND _PIP_BINDIR "${PIP_DIR}/bin")
set(_pip_suffix "") set(_pip_suffix "")
#if(DEFINED ANDROID_PLATFORM)
# set(_pip_suffix "_${ANDROID_ABI}")
#endif()
find_library(PIP_LIBRARY pip${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_LIBRARY pip${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_USB_LIBRARY pip_usb${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_USB_LIBRARY pip_usb${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_CONSOLE_LIBRARY pip_console${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_CRYPT_LIBRARY pip_crypt${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CRYPT_LIBRARY pip_crypt${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_FFTW_LIBRARY pip_fftw${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_FFTW_LIBRARY pip_fftw${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_COMPRESS_LIBRARY pip_compress${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_COMPRESS_LIBRARY pip_compress${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_OPENCL_LIBRARY pip_opencl${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_IO_UTILS_LIBRARY pip_io_utils${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_IO_UTILS_LIBRARY pip_io_utils${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_CONCURRENT_LIBRARY pip_concurrent${_pip_suffix} HINTS ${_PIP_LIBDIR})
find_library(PIP_CLOUD_LIBRARY pip_cloud HINTS${_pip_suffix} ${_PIP_LIBDIR}) find_library(PIP_CLOUD_LIBRARY pip_cloud HINTS${_pip_suffix} ${_PIP_LIBDIR})
find_library(PIP_LUA_LIBRARY pip_lua HINTS${_pip_suffix} ${_PIP_LIBDIR})
find_file(PIP_H_INCLUDE "pip.h" HINTS ${_PIP_INCDIR} $ENV{SMSDK_DIR}/include/pip) find_file(PIP_H_INCLUDE "pip.h" HINTS ${_PIP_INCDIR} $ENV{SMSDK_DIR}/include/pip)
#if (DEFINED ANDROID_PLATFORM) get_filename_component(PIP_INCLUDES ${PIP_H_INCLUDE} PATH)
# set(PIP_INCLUDES ${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include/pip) set(__ext "")
#else() if ("x${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "xWindows")
get_filename_component(PIP_INCLUDES ${PIP_H_INCLUDE} PATH) set(__ext ".exe")
#endif() if (CMAKE_CROSSCOMPILING)
find_program(PIP_CMG pip_cmg HINTS ${_PIP_BINDIR} ${_PIP_FP_DP}) set(_PIP_FP_DP)
find_program(PIP_RC pip_rc HINTS ${_PIP_BINDIR} ${_PIP_FP_DP}) endif()
endif()
#message("FIND \"${__ext}\" -> ${_PIP_BINDIR}")
find_program(PIP_CMG pip_cmg${__ext} HINTS ${_PIP_BINDIR} ${_PIP_FP_DP})
find_program(PIP_RC pip_rc${__ext} HINTS ${_PIP_BINDIR} ${_PIP_FP_DP})
find_program(PIP_DEPLOY_TOOL deploy_tool${__ext} HINTS ${_PIP_BINDIR} ${_PIP_FP_DP})
if (NOT PIP_LIBRARY) if (NOT PIP_LIBRARY)
message(FATAL_ERROR "Can`t find PIP library!") message(FATAL_ERROR "Can`t find PIP library!")
endif() endif()
@@ -95,6 +96,19 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
list(APPEND PIP_LIBRARY ${_PIP_ADD_LIBS_}) list(APPEND PIP_LIBRARY ${_PIP_ADD_LIBS_})
endif() endif()
endif() endif()
if(PIP_LUA_LIBRARY)
if (NOT LUA_FOUND)
if(MINGW)
set(LUA_INCLUDE_DIR ${MINGW_INCLUDE})
set(_prev_clp "${CMAKE_LIBRARY_PATH}")
set(CMAKE_LIBRARY_PATH "${MINGW_LIB}")
endif()
find_package(Lua QUIET)
if(MINGW)
set(CMAKE_LIBRARY_PATH "${_prev_clp}")
endif()
endif()
endif()
if(NOT PIP_VERSION) if(NOT PIP_VERSION)
include(CheckSymbolExists) include(CheckSymbolExists)
@@ -118,14 +132,16 @@ if(PIP_FIND_VERSION VERSION_GREATER PIP_VERSION)
message(FATAL_ERROR "PIP version ${PIP_VERSION} is available, but ${PIP_FIND_VERSION} requested!") message(FATAL_ERROR "PIP version ${PIP_VERSION} is available, but ${PIP_FIND_VERSION} requested!")
endif() endif()
set(__modules "USB;Crypt;FFTW;Compress;IOUtils;Concurrent;Cloud") set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Cloud;Lua")
set(__module_USB "${PIP_USB_LIBRARY}" ) set(__module_USB "${PIP_USB_LIBRARY}" )
set(__module_Console "${PIP_CONSOLE_LIBRARY}" )
set(__module_Crypt "${PIP_CRYPT_LIBRARY}" ) set(__module_Crypt "${PIP_CRYPT_LIBRARY}" )
set(__module_FFTW "${PIP_FFTW_LIBRARY}" ) set(__module_FFTW "${PIP_FFTW_LIBRARY}" )
set(__module_Compress "${PIP_COMPRESS_LIBRARY}" ) set(__module_Compress "${PIP_COMPRESS_LIBRARY}" )
set(__module_OpenCL "${PIP_OPENCL_LIBRARY}" )
set(__module_IOUtils "${PIP_IO_UTILS_LIBRARY}" ) set(__module_IOUtils "${PIP_IO_UTILS_LIBRARY}" )
set(__module_Concurrent "${PIP_CONCURRENT_LIBRARY}")
set(__module_Cloud "${PIP_CLOUD_LIBRARY}" ) set(__module_Cloud "${PIP_CLOUD_LIBRARY}" )
set(__module_Lua "${PIP_LUA_LIBRARY}" )
if((NOT TARGET PIP) AND PIP_LIBRARY) if((NOT TARGET PIP) AND PIP_LIBRARY)
add_library(PIP UNKNOWN IMPORTED) add_library(PIP UNKNOWN IMPORTED)
set_target_properties(PIP PROPERTIES set_target_properties(PIP PROPERTIES
@@ -141,8 +157,15 @@ foreach (_m ${__modules})
INTERFACE_LINK_LIBRARIES "PIP") INTERFACE_LINK_LIBRARIES "PIP")
endif() endif()
endforeach() endforeach()
set_target_properties(PIP::IOUtils PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::Crypt") if(__module_IOUtils AND __module_Crypt)
set_target_properties(PIP::Cloud PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::IOUtils") set_target_properties(PIP::IOUtils PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::Crypt")
endif()
if(__module_Cloud AND __module_IOUtils)
set_target_properties(PIP::Cloud PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::IOUtils")
endif()
if(__module_Lua)
set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}" INTERFACE_LINK_LIBRARIES "PIP;${LUA_LIBRARIES}")
endif()
include(PIPMacros) include(PIPMacros)

View File

@@ -1,27 +1,6 @@
macro(CONFIGURE_DOXYGEN_FILE DOXYGEN_CONFIG_FILE FILE_NAME_SUFFIX)
if(EXISTS ${PROJECT_SOURCE_DIR}/${DOXYGEN_CONFIG_FILE})
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${FILE_NAME_SUFFIX}")
file(READ ${PROJECT_SOURCE_DIR}/${DOXYGEN_CONFIG_FILE} DOXYFILE_CONTENTS)
string(REPLACE "\\\n" " " DOXYFILE_CONTENTS "${DOXYFILE_CONTENTS}")
string(REPLACE "\n" ";" DOXYFILE_LINES "${DOXYFILE_CONTENTS}")
foreach(LINE IN LISTS DOXYFILE_LINES)
if(LINE STRGREATER "")
string(REGEX MATCH "^[a-zA-Z]([^ ])+" DOXY_PARAM ${LINE})
if(DEFINED DOXY_${DOXY_PARAM})
STRING(REGEX REPLACE "=([^\n])+" "= ${DOXY_${DOXY_PARAM}}" LINE ${LINE})
endif(DEFINED DOXY_${DOXY_PARAM})
endif()
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${FILE_NAME_SUFFIX} "${LINE}\n")
endforeach()
else()
MESSAGE(SEND_ERROR "Doxygen configuration file '${DOXYGEN_CONFIG_FILE}' not found, can`t generate documentation")
endif()
endmacro(CONFIGURE_DOXYGEN_FILE)
macro(ADD_DOCUMENTATION TARGET DOXYGEN_CONFIG_FILE) macro(ADD_DOCUMENTATION TARGET DOXYGEN_CONFIG_FILE)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
configure_doxygen_file(${DOXYGEN_CONFIG_FILE} ${TARGET}) configure_file("${PROJECT_SOURCE_DIR}/${DOXYGEN_CONFIG_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${TARGET}")
add_custom_target("genereate.${TARGET}" COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${TARGET}) add_custom_target("genereate.${TARGET}" COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${TARGET})
add_custom_target("${TARGET}" COMMAND ${CMAKE_COMMAND} -D COMPONENT=doc -P cmake_install.cmake) add_custom_target("${TARGET}" COMMAND ${CMAKE_COMMAND} -D COMPONENT=doc -P cmake_install.cmake)
add_dependencies("${TARGET}" "genereate.${TARGET}") add_dependencies("${TARGET}" "genereate.${TARGET}")

View File

@@ -86,17 +86,11 @@ macro(pip_resources RESULT INPUT)
set(RC_OUT ${CMAKE_CURRENT_BINARY_DIR}/${RC_FILE}) set(RC_OUT ${CMAKE_CURRENT_BINARY_DIR}/${RC_FILE})
set(${RESULT} ${${RESULT}} ${RC_OUT}) set(${RESULT} ${${RESULT}} ${RC_OUT})
set(CCM_FILES) set(CCM_FILES)
#if (ABS)
if(IS_ABSOLUTE "${INPUT}") if(IS_ABSOLUTE "${INPUT}")
set(RC_FILES "${INPUT}") set(RC_FILES "${INPUT}")
else() else()
set(RC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}") set(RC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}")
endif() endif()
#else()
# foreach(csrc ${CCM_SRC})
# list(APPEND CCM_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${csrc}")
# endforeach()
#endif()
#message(STATUS "CCM = ${RESULT}") #message(STATUS "CCM = ${RESULT}")
if(NOT DEFINED PIP_DLL_DIR) if(NOT DEFINED PIP_DLL_DIR)
set(PIP_DLL_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(PIP_DLL_DIR ${CMAKE_CURRENT_BINARY_DIR})

View File

@@ -1,5 +1,6 @@
androidBuildToolsVersion= androidBuildToolsVersion=
androidCompileSdkVersion=@ANDROID_TARGET_SDK@ androidCompileSdkVersion=@ANDROID_TARGET_SDK@
android.bundle.enableUncompressedNativeLibs=@ANDROID_NEW_LOADER@
buildDir=build buildDir=build
qt5AndroidDir=@Qt5_ROOT@/src/android/java qt5AndroidDir=@Qt5_ROOT@/src/android/java
DEBUG_STORE_FILE=@__ANDROID_DEBUG_KEYSTORE__@ DEBUG_STORE_FILE=@__ANDROID_DEBUG_KEYSTORE__@

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = PIP
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 1.8.0 PROJECT_NUMBER = ${DOXY_PROJECT_NUMBER}
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a
@@ -816,13 +816,7 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched. # Note: If this tag is empty the current directory is searched.
INPUT = src_main \ INPUT = ${DOXY_INPUT}
src_crypt \
src_fftw \
src_io_utils \
src_compress \
src_opencl \
src_usb
# This tag can be used to specify the character encoding of the source files # This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
@@ -895,7 +889,7 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is # Note that relative paths are relative to the directory from which doxygen is
# run. # run.
EXCLUDE = EXCLUDE = ${DOXY_EXCLUDE}
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded # directories that are symbolic links (a Unix file system feature) are excluded
@@ -928,7 +922,7 @@ EXCLUDE_SYMBOLS =
# that contain example code fragments that are included (see the \include # that contain example code fragments that are included (see the \include
# command). # command).
EXAMPLE_PATH = doc/examples EXAMPLE_PATH = ${DOXY_EXAMPLE_PATH}
# If the value of the EXAMPLE_PATH tag contains directories, you can use the # If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
@@ -948,7 +942,7 @@ EXAMPLE_RECURSIVE = NO
# that contain images that are to be included in the documentation (see the # that contain images that are to be included in the documentation (see the
# \image command). # \image command).
IMAGE_PATH = doc/images IMAGE_PATH = ${DOXY_IMAGE_PATH}
# The INPUT_FILTER tag can be used to specify a program that doxygen should # The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program # invoke to filter for each input file. Doxygen will invoke the filter program
@@ -1459,14 +1453,14 @@ QHP_CUST_FILTER_NAME = PIP
# filters). # filters).
# This tag requires that the tag GENERATE_QHP is set to YES. # This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS = PIP QHP_CUST_FILTER_ATTRS = ${DOXY_QHP_CUST_FILTER_ATTRS}
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see: # project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES. # This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS = PIP QHP_SECT_FILTER_ATTRS = ${DOXY_QHP_SECT_FILTER_ATTRS}
# The QHG_LOCATION tag can be used to specify the location of Qt's # The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
@@ -2152,15 +2146,7 @@ SEARCH_INCLUDES = YES
# preprocessor. # preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES. # This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH = src_main/code \ INCLUDE_PATH = ${DOXY_INCLUDE_PATH}
src_main/containers \
src_main/core \
src_main/math \
src_main/system \
src_main/thread \
src_main/console \
src_main/io_devices \
src_main/io_utils
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the # patterns (like *.h and *.hpp) to filter out the header-files in the
@@ -2178,8 +2164,8 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator. # recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED = DOXYGEN \ PREDEFINED = ${DOXY_DEFINES}
PIP_EXPORT
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The # tag can be used to specify a list of macro names that should be expanded. The
@@ -2272,14 +2258,14 @@ CLASS_DIAGRAMS = YES
# the mscgen tool resides. If left empty the tool is assumed to be found in the # the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path. # default search path.
MSCGEN_PATH = "C:/Program Files/doxygen/graphviz/bin" MSCGEN_PATH = ${DOXY_MSCGEN_PATH}
# You can include diagrams made with dia in doxygen documentation. Doxygen will # You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The # then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides. # DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path. # If left empty dia is assumed to be found in the default search path.
DIA_PATH = "C:/Program Files/doxygen/graphviz/bin" DIA_PATH = ${DOXY_DIA_PATH}
# If set to YES the inheritance and collaboration graphs will hide inheritance # If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class. # and usage relations if the target is undocumented or is not a class.
@@ -2472,7 +2458,7 @@ INTERACTIVE_SVG = NO
# found. If left blank, it is assumed the dot tool can be found in the path. # found. If left blank, it is assumed the dot tool can be found in the path.
# This tag requires that the tag HAVE_DOT is set to YES. # This tag requires that the tag HAVE_DOT is set to YES.
DOT_PATH = "C:/Program Files/doxygen/graphviz/bin" DOT_PATH = ${DOXY_DOT_PATH}
# The DOTFILE_DIRS tag can be used to specify one or more directories that # The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the \dotfile # contain dot files that are included in the documentation (see the \dotfile

View File

@@ -211,6 +211,16 @@ piCout << s.find("3"); // 9
piCout << s.find("3", 4); // 9 piCout << s.find("3", 4); // 9
piCout << s.find("3", 10); // -1 piCout << s.find("3", 10); // -1
//! [PIString::findLast] //! [PIString::findLast]
//! [PIString::findAny]
piCout << PIString("1.str").findAny(".,:"); // 1
piCout << PIString("1,str").findAny(".,:"); // 1
piCout << PIString("1:str").findAny(".,:"); // 1
//! [PIString::findAny]
//! [PIString::findAnyLast]
piCout << PIString("str.0").findAny(".,:"); // 3
piCout << PIString("str,0").findAny(".,:"); // 3
piCout << PIString("str:0").findAny(".,:"); // 3
//! [PIString::findAnyLast]
//! [PIString::findWord] //! [PIString::findWord]
PIString s("this is <PIP>"); PIString s("this is <PIP>");
piCout << s.find("this"); // 0 piCout << s.find("this"); // 0

View File

@@ -1,22 +1,21 @@
set(COMPONENT_SRCS "main.cpp") set(COMPONENT_SRCS "main.cpp")
set(COMPONENT_ADD_INCLUDEDIRS "pip/src_main") set(COMPONENT_ADD_INCLUDEDIRS "pip/lib/main")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/auxiliary") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/auxiliary")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/code") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/code")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/console") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/console")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/containers") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/containers")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/core") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/core")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/crypt") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/crypt")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/geo") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/geo")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/io_devices") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/io_devices")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/io_utils") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/io_utils")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/math") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/math")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/opencl") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/opencl")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/resources") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/resources")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/system") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/system")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/thread") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/thread")
list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/src_main/introspection") list(APPEND COMPONENT_ADD_INCLUDEDIRS "pip/lib/main/introspection")
set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spiffs) set(COMPONENT_PRIV_REQUIRES pthread lwip freertos vfs spiffs)
#set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
register_component() register_component()
set(PIP_FREERTOS ON) set(PIP_FREERTOS ON)
set(LIB OFF) set(LIB OFF)

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PICloud Client PICloud Client
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -23,3 +23,18 @@
PICloudClient::PICloudClient() { PICloudClient::PICloudClient() {
} }
PICloudClient::~PICloudClient() {
}
bool PICloudClient::openDevice() {
}
bool PICloudClient::closeDevice() {
}

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PICloud Server PICloud Server
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PICloud TCP transport PICloud TCP transport
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Cryptographic class using lib Sodium Compress class using zlib
Copyright (C) 2020 Andrey Bychkov work.a.b@yandex.ru Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console output/input Console output/input
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "piscreen.h" #include "piscreen.h"
@@ -162,7 +162,6 @@ void PIScreen::SystemConsole::print() {
///cells[mouse_y][mouse_x].format.flags ^= Inverse; ///cells[mouse_y][mouse_x].format.flags ^= Inverse;
} }
#ifdef WINDOWS #ifdef WINDOWS
//static int cnt = 0;
PRIVATE->srect = PRIVATE->sbi.srWindow; PRIVATE->srect = PRIVATE->sbi.srWindow;
int dx0 = -1, dx1 = -1, dy0 = -1, dy1 = -1; int dx0 = -1, dx1 = -1, dy0 = -1, dy1 = -1;
for (int j = 0; j < height; ++j) { for (int j = 0; j < height; ++j) {
@@ -189,11 +188,8 @@ void PIScreen::SystemConsole::print() {
Cell & c(cells[j + dy0][i + dx0]); Cell & c(cells[j + dy0][i + dx0]);
PRIVATE->chars[k].Char.UnicodeChar = 0; PRIVATE->chars[k].Char.UnicodeChar = 0;
PRIVATE->chars[k].Char.AsciiChar = c.symbol.toConsole1Byte(); PRIVATE->chars[k].Char.AsciiChar = c.symbol.toConsole1Byte();
//PRIVATE->chars[k].Char.UnicodeChar = c.symbol.toInt();
PRIVATE->chars[k].Attributes = attributes(c); PRIVATE->chars[k].Attributes = attributes(c);
} }
//PRIVATE->bc.X = dx0;
//PRIVATE->bc.Y = dy0;
//piCout << "draw" << dw << dh; //piCout << "draw" << dw << dh;
PRIVATE->bs.X = dw; PRIVATE->bs.X = dw;
PRIVATE->bs.Y = dh; PRIVATE->bs.Y = dh;
@@ -235,10 +231,6 @@ void PIScreen::SystemConsole::print() {
printf("%s", s.data()); printf("%s", s.data());
s.clear(); s.clear();
} }
/*for (int i = 0; i < width; ++i) {
moveTo(i, j);
printf("%s", (formatString(cells[j][i]) + cells[j][i].symbol).data());
}*/
} }
printf("\e[0m"); printf("\e[0m");
fflush(0); fflush(0);
@@ -420,9 +412,7 @@ PIScreen::~PIScreen() {
void PIScreen::setMouseEnabled(bool on) { void PIScreen::setMouseEnabled(bool on) {
mouse_ = on; mouse_ = on;
//lock();
console.mouse_x = console.mouse_y = -1; console.mouse_x = console.mouse_y = -1;
//unlock();
} }
@@ -490,7 +480,7 @@ void PIScreen::mouse_event(PIKbdListener::MouseEvent me) {
PIVector<PIScreenTile * > tl = prepareMouse(&me); PIVector<PIScreenTile * > tl = prepareMouse(&me);
if (tl.isEmpty()) return; if (tl.isEmpty()) return;
piForeachR (PIScreenTile * t, tl) piForeachR (PIScreenTile * t, tl)
if (t->mouseEvent(me)) piBreak; if (t->mouseEvent(me)) break;
} }
@@ -498,7 +488,7 @@ void PIScreen::wheel_event(PIKbdListener::WheelEvent we) {
PIVector<PIScreenTile * > tl = prepareMouse(&we); PIVector<PIScreenTile * > tl = prepareMouse(&we);
if (tl.isEmpty()) return; if (tl.isEmpty()) return;
piForeachR (PIScreenTile * t, tl) piForeachR (PIScreenTile * t, tl)
if (t->wheelEvent(we)) piBreak; if (t->wheelEvent(we)) break;
} }

View File

@@ -0,0 +1,42 @@
/*
PIP - Platform Independent Primitives
Tile for PIScreen with PIConsole API
Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piscreenconsole.h"
using namespace PIScreenTypes;
TileVars::TileVars(const PIString &n) : PIScreenTile(n) {
alignment = Left;
}
void TileVars::sizeHint(int &w, int &h) const {
}
void TileVars::drawEvent(PIScreenDrawer *d) {
}
PIScreenConsoleTile::PIScreenConsoleTile() {
}

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console output/input Console output/input
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Basic PIScreen tile Basic PIScreen tile
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -111,10 +111,7 @@ void PIScreenTile::setScreen(PIScreenBase * s) {
void PIScreenTile::deleteChildren() { void PIScreenTile::deleteChildren() {
//piCout << this << "deleteChildren";
piForeach (PIScreenTile * t, tiles) { piForeach (PIScreenTile * t, tiles) {
//piCout << this << " child" << t;
//t->deleteChildren();
t->parent = 0; t->parent = 0;
delete t; delete t;
} }
@@ -130,7 +127,6 @@ void PIScreenTile::setFocus() {
void PIScreenTile::drawEventInternal(PIScreenDrawer * d) { void PIScreenTile::drawEventInternal(PIScreenDrawer * d) {
if (!visible) { if (!visible) {
//d->clearRect(x, y, x + width, y + height);
return; return;
} }
d->fillRect(x_, y_, x_ + width_, y_ + height_, back_symbol, (Color)back_format.color_char, (Color)back_format.color_back, back_format.flags); d->fillRect(x_, y_, x_ + width_, y_ + height_, back_symbol, (Color)back_format.color_char, (Color)back_format.color_back, back_format.flags);
@@ -232,7 +228,7 @@ void PIScreenTile::layout() {
} }
int cx = x_ + marginLeft, cy = y_ + marginTop; int cx = x_ + marginLeft, cy = y_ + marginTop;
for (int i = 0; i < tiles.size_s(); ++i) { for (int i = 0; i < tiles.size_s(); ++i) {
PIScreenTile * t(tiles[i]); PIScreenTile * t = tiles[i];
if (!t->visible || !t->needLayout()) continue; if (!t->visible || !t->needLayout()) continue;
t->x_ = cx; t->x_ = cx;
t->y_ = cy; t->y_ = cy;

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Various tiles for PIScreen Various tiles for PIScreen
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -154,7 +154,6 @@ void TileList::resizeEvent(int w, int h) {
void TileList::drawEvent(PIScreenDrawer * d) { void TileList::drawEvent(PIScreenDrawer * d) {
lhei = height_ - 2; lhei = height_ - 2;
//int osp = piMini(3, lhei / 4);
int is = piClampi(offset, 0, piMaxi(0, content.size_s() - 1)), ie = piClampi(offset + lhei, 0, content.size_s()); int is = piClampi(offset, 0, piMaxi(0, content.size_s() - 1)), ie = piClampi(offset + lhei, 0, content.size_s());
if (is > 0) d->drawText(x_, y_, PIString(" /\\ ").repeat(width_ / 4), Green, Default, Bold); if (is > 0) d->drawText(x_, y_, PIString(" /\\ ").repeat(width_ / 4), Green, Default, Bold);
if (ie < content.size_s()) d->drawText(x_, y_ + height_ - 1, PIString(" \\/ ").repeat(width_ / 4), Green, Default, Bold); if (ie < content.size_s()) d->drawText(x_, y_ + height_ - 1, PIString(" \\/ ").repeat(width_ / 4), Green, Default, Bold);
@@ -182,11 +181,6 @@ void TileList::drawEvent(PIScreenDrawer * d) {
} }
scroll->setMaximum(piMaxi(0, content.size_s() - 1)); scroll->setMaximum(piMaxi(0, content.size_s() - 1));
scroll->setValue(cur); scroll->setValue(cur);
/*int cx = x_ + width_ - 1;
d->drawLine(cx, y_ + 1, cx, y_ + height_ - 2, vert_line, Green);
if (content.size_s() > 1)
d->drawPixel(cx, y_ + piRound(float(cur) / (content.size_s() - 1) * (lhei - 1)) + 1, ' ', Green, Green);
if (ie < content.size_s()) d->drawText(x_, y_ + height_ - 1, PIString(" \\/ ").repeat(width_ / 4), Green, Default, Bold);*/
} }
@@ -289,7 +283,6 @@ bool TileList::mouseEvent(PIKbdListener::MouseEvent me) {
break; break;
case PIKbdListener::MouseButtonDblClick: case PIKbdListener::MouseButtonDblClick:
keyEvent(PIKbdListener::KeyEvent(PIKbdListener::Return)); keyEvent(PIKbdListener::KeyEvent(PIKbdListener::Return));
//raiseEvent(TileEvent(RowPressed, cur));
return true; return true;
default: break; default: break;
} }

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Virtual terminal Virtual terminal
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "piincludes_p.h" #include "piincludes_p.h"
@@ -805,7 +805,7 @@ bool PITerminal::initialize() {
if (e.startsWith("TERM=")) { if (e.startsWith("TERM=")) {
PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase()); PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase());
//piCout << PRIVATE->term_type; //piCout << PRIVATE->term_type;
piBreak; break;
} }
pid_t fr = forkpty(&(PRIVATE->fd), pty, 0, &ws); pid_t fr = forkpty(&(PRIVATE->fd), pty, 0, &ws);
//piCoutObj << fr << PRIVATE->fd << pty; //piCoutObj << fr << PRIVATE->fd << pty;

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PIP Authentication API PIP Authentication API
Copyright (C) 2020 Andrey Bychkov work.a.b@yandex.ru Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Cryptographic class using lib Sodium Cryptographic class using lib Sodium
Copyright (C) 2020 Andrey Bychkov work.a.b@yandex.ru Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Class for FFT, IFFT and Hilbert transformations Class for FFT, IFFT and Hilbert transformations
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Private header for fftw3 Private header for fftw3
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -24,7 +24,6 @@
#define PIFFT_P_H #define PIFFT_P_H
#include "pivector.h" #include "pivector.h"
#include "pimutex.h"
#include "picout.h" #include "picout.h"
#if defined(PIP_FFTW) || defined(PIP_FFTWf) || defined(PIP_FFTWl) || defined(PIP_FFTWq) #if defined(PIP_FFTW) || defined(PIP_FFTWf) || defined(PIP_FFTWl) || defined(PIP_FFTWq)
# include "fftw3.h" # include "fftw3.h"
@@ -37,7 +36,7 @@
template <typename T> template <typename T>
class PIP_EXPORT PIFFTW_Private class PIFFTW_Private
{ {
public: public:
explicit PIFFTW_Private() { explicit PIFFTW_Private() {

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Broadcast for all interfaces, including loopback Broadcast for all interfaces, including loopback
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Base class for ethernet utils Base class for ethernet utils
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -55,6 +55,32 @@ PIEthUtilBase::~PIEthUtilBase() {
} }
void PIEthUtilBase::setCryptEnabled(bool on) {
_crypt = on;
}
void PIEthUtilBase::cryptEnable() {
setCryptEnabled(true);
}
void PIEthUtilBase::cryptDisable() {
setCryptEnabled(false);
}
bool PIEthUtilBase::isCryptEnabled() const {
return _crypt;
}
void PIEthUtilBase::setCryptKey(const PIByteArray & k) {
_key = k;
setCryptEnabled(true);
}
void PIEthUtilBase::createCryptKey(const PIString & k) { void PIEthUtilBase::createCryptKey(const PIString & k) {
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
_key = PICrypt::hash("sodium_bug"); _key = PICrypt::hash("sodium_bug");
@@ -66,6 +92,11 @@ void PIEthUtilBase::createCryptKey(const PIString & k) {
} }
PIByteArray PIEthUtilBase::cryptKey() const {
return _key;
}
PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) { PIByteArray PIEthUtilBase::cryptData(const PIByteArray & data) {
if (!_crypt) return data; if (!_crypt) return data;
return return

View File

@@ -1,24 +1,31 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Simple packet wrap aroud any PIIODevice Simple packet wrap aroud any PIIODevice
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifdef __GNUC__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wnonnull"
#endif
#include "pistreampacker.h" #include "pistreampacker.h"
#include "piiodevice.h" #include "piiodevice.h"
#ifdef __GNUC__
# pragma GCC diagnostic pop
#endif
/** \class PIStreamPacker /** \class PIStreamPacker
* \brief Simple packet wrap aroud any PIIODevice * \brief Simple packet wrap aroud any PIIODevice
@@ -107,7 +114,7 @@ void PIStreamPacker::received(uchar * readed, int size) {
void PIStreamPacker::received(const PIByteArray & data) { void PIStreamPacker::received(const PIByteArray & data) {
stream.append(data); stream.append(data);
//piCout << "rec" << data.size(); //piCout << "rec" << data.size();
while (stream.size_s() >= 4) { while (stream.size_s() >= 6) {
if (packet_size < 0) { if (packet_size < 0) {
ushort sign(0); ushort sign(0);
memcpy(&sign, stream.data(), 2); memcpy(&sign, stream.data(), 2);

View File

@@ -0,0 +1,55 @@
// https://github.com/vinniefalco/LuaBridge
//
// Copyright 2018, Dmitry Tarakanov
// SPDX-License-Identifier: MIT
#pragma once
#include <LuaBridge/detail/Stack.h>
#include <list>
namespace luabridge {
template <class T>
struct Stack <std::list <T> >
{
static void push (lua_State* L, std::list <T> const& list)
{
lua_createtable (L, static_cast <int> (list.size ()), 0);
typename std::list <T>::const_iterator item = list.begin ();
for (std::size_t i = 1; i <= list.size (); ++i)
{
lua_pushinteger (L, static_cast <lua_Integer> (i));
Stack <T>::push (L, *item);
lua_settable (L, -3);
++item;
}
}
static std::list <T> get (lua_State* L, int index)
{
if (!lua_istable (L, index))
{
luaL_error (L, "#%d argument must be a table", index);
}
std::list <T> list;
int const absindex = lua_absindex (L, index);
lua_pushnil (L);
while (lua_next (L, absindex) != 0)
{
list.push_back (Stack <T>::get (L, -1));
lua_pop (L, 1);
}
return list;
}
static bool isInstance (lua_State* L, int index)
{
return lua_istable (L, index);
}
};
} // namespace luabridge

View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
// All #include dependencies are listed here
// instead of in the individual header files.
//
#define LUABRIDGE_MAJOR_VERSION 2
#define LUABRIDGE_MINOR_VERSION 3
#define LUABRIDGE_VERSION 203
#ifndef LUA_VERSION_NUM
#error "Lua headers must be included prior to LuaBridge ones"
#endif
#include <LuaBridge/detail/LuaHelpers.h>
#include <LuaBridge/detail/TypeTraits.h>
#include <LuaBridge/detail/TypeList.h>
#include <LuaBridge/detail/FuncTraits.h>
#include <LuaBridge/detail/Constructor.h>
#include <LuaBridge/detail/ClassInfo.h>
#include <LuaBridge/detail/LuaException.h>
#include <LuaBridge/detail/LuaRef.h>
#include <LuaBridge/detail/Iterator.h>
#include <LuaBridge/detail/Userdata.h>
#include <LuaBridge/detail/CFunctions.h>
#include <LuaBridge/detail/Security.h>
#include <LuaBridge/detail/Stack.h>
#include <LuaBridge/detail/Namespace.h>

View File

@@ -0,0 +1,56 @@
// https://github.com/vinniefalco/LuaBridge
//
// Copyright 2018, Dmitry Tarakanov
// SPDX-License-Identifier: MIT
#pragma once
#include <LuaBridge/detail/Stack.h>
#include <LuaBridge/detail/dump.h>
#include <map>
namespace luabridge {
template <class K, class V>
struct Stack <std::map <K, V> >
{
typedef std::map <K, V> Map;
static void push (lua_State* L, const Map& map)
{
lua_createtable (L, 0, static_cast <int> (map.size ()));
typedef typename Map::const_iterator ConstIter;
for (ConstIter i = map.begin (); i != map.end (); ++i)
{
Stack <K>::push (L, i->first);
Stack <V>::push (L, i->second);
lua_settable (L, -3);
}
}
static Map get (lua_State* L, int index)
{
if (!lua_istable (L, index))
{
luaL_error (L, "#%d argument must be a table", index);
}
Map map;
int const absindex = lua_absindex (L, index);
lua_pushnil (L);
while (lua_next (L, absindex) != 0)
{
map.emplace (Stack <K>::get (L, -2), Stack <V>::get (L, -1));
lua_pop (L, 1);
}
return map;
}
static bool isInstance (lua_State* L, int index)
{
return lua_istable (L, index);
}
};
} // namespace luabridge

View File

@@ -0,0 +1,356 @@
//==============================================================================
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2004-11 by Raw Material Software Ltd.
This is a derivative work used by permission from part of
JUCE, available at http://www.rawaterialsoftware.com
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This file incorporates work covered by the following copyright and
permission notice:
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-11 by Raw Material Software Ltd.
*/
//==============================================================================
#pragma once
//#define LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1
#include <LuaBridge/detail/TypeTraits.h>
#include <cassert>
namespace luabridge {
//==============================================================================
/**
Adds reference-counting to an object.
To add reference-counting to a class, derive it from this class, and
use the RefCountedObjectPtr class to point to it.
e.g. @code
class MyClass : public RefCountedObjectType
{
void foo();
// This is a neat way of declaring a typedef for a pointer class,
// rather than typing out the full templated name each time..
typedef RefCountedObjectPtr<MyClass> Ptr;
};
MyClass::Ptr p = new MyClass();
MyClass::Ptr p2 = p;
p = 0;
p2->foo();
@endcode
Once a new RefCountedObjectType has been assigned to a pointer, be
careful not to delete the object manually.
*/
template <class CounterType>
class RefCountedObjectType
{
public:
//==============================================================================
/** Increments the object's reference count.
This is done automatically by the smart pointer, but is public just
in case it's needed for nefarious purposes.
*/
inline void incReferenceCount() const
{
++refCount;
}
/** Decreases the object's reference count.
If the count gets to zero, the object will be deleted.
*/
inline void decReferenceCount() const
{
assert (getReferenceCount() > 0);
if (--refCount == 0)
delete this;
}
/** Returns the object's current reference count. */
inline int getReferenceCount() const
{
return static_cast <int> (refCount);
}
protected:
//==============================================================================
/** Creates the reference-counted object (with an initial ref count of zero). */
RefCountedObjectType() : refCount ()
{
}
/** Destructor. */
virtual ~RefCountedObjectType()
{
// it's dangerous to delete an object that's still referenced by something else!
assert (getReferenceCount() == 0);
}
private:
//==============================================================================
CounterType mutable refCount;
};
//==============================================================================
/** Non thread-safe reference counted object.
This creates a RefCountedObjectType that uses a non-atomic integer
as the counter.
*/
typedef RefCountedObjectType <int> RefCountedObject;
//==============================================================================
/**
A smart-pointer class which points to a reference-counted object.
The template parameter specifies the class of the object you want to point
to - the easiest way to make a class reference-countable is to simply make
it inherit from RefCountedObjectType, but if you need to, you could roll
your own reference-countable class by implementing a pair of methods called
incReferenceCount() and decReferenceCount().
When using this class, you'll probably want to create a typedef to
abbreviate the full templated name - e.g.
@code
typedef RefCountedObjectPtr <MyClass> MyClassPtr;
@endcode
*/
template <class ReferenceCountedObjectClass>
class RefCountedObjectPtr
{
public:
/** The class being referenced by this pointer. */
typedef ReferenceCountedObjectClass ReferencedType;
//==============================================================================
/** Creates a pointer to a null object. */
inline RefCountedObjectPtr() : referencedObject (0)
{
}
/** Creates a pointer to an object.
This will increment the object's reference-count if it is non-null.
*/
inline RefCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject)
: referencedObject (refCountedObject)
{
if (refCountedObject != 0)
refCountedObject->incReferenceCount();
}
/** Copies another pointer.
This will increment the object's reference-count (if it is non-null).
*/
inline RefCountedObjectPtr (const RefCountedObjectPtr& other)
: referencedObject (other.referencedObject)
{
if (referencedObject != 0)
referencedObject->incReferenceCount();
}
#if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Takes-over the object from another pointer. */
inline RefCountedObjectPtr (RefCountedObjectPtr&& other)
: referencedObject (other.referencedObject)
{
other.referencedObject = 0;
}
#endif
/** Copies another pointer.
This will increment the object's reference-count (if it is non-null).
*/
template <class DerivedClass>
inline RefCountedObjectPtr (const RefCountedObjectPtr<DerivedClass>& other)
: referencedObject (static_cast <ReferenceCountedObjectClass*> (other.getObject()))
{
if (referencedObject != 0)
referencedObject->incReferenceCount();
}
/** Changes this pointer to point at a different object.
The reference count of the old object is decremented, and it might be
deleted if it hits zero. The new object's count is incremented.
*/
RefCountedObjectPtr& operator= (const RefCountedObjectPtr& other)
{
return operator= (other.referencedObject);
}
/** Changes this pointer to point at a different object.
The reference count of the old object is decremented, and it might be
deleted if it hits zero. The new object's count is incremented.
*/
template <class DerivedClass>
RefCountedObjectPtr& operator= (const RefCountedObjectPtr<DerivedClass>& other)
{
return operator= (static_cast <ReferenceCountedObjectClass*> (other.getObject()));
}
#if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Takes-over the object from another pointer. */
RefCountedObjectPtr& operator= (RefCountedObjectPtr&& other)
{
std::swap (referencedObject, other.referencedObject);
return *this;
}
#endif
/** Changes this pointer to point at a different object.
The reference count of the old object is decremented, and it might be
deleted if it hits zero. The new object's count is incremented.
*/
RefCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject)
{
if (referencedObject != newObject)
{
if (newObject != 0)
newObject->incReferenceCount();
ReferenceCountedObjectClass* const oldObject = referencedObject;
referencedObject = newObject;
if (oldObject != 0)
oldObject->decReferenceCount();
}
return *this;
}
/** Destructor.
This will decrement the object's reference-count, and may delete it if it
gets to zero.
*/
inline ~RefCountedObjectPtr()
{
if (referencedObject != 0)
referencedObject->decReferenceCount();
}
/** Returns the object that this pointer references.
The pointer returned may be zero, of course.
*/
inline operator ReferenceCountedObjectClass*() const
{
return referencedObject;
}
// the -> operator is called on the referenced object
inline ReferenceCountedObjectClass* operator->() const
{
return referencedObject;
}
/** Returns the object that this pointer references.
The pointer returned may be zero, of course.
*/
inline ReferenceCountedObjectClass* getObject() const
{
return referencedObject;
}
private:
//==============================================================================
ReferenceCountedObjectClass* referencedObject;
};
/** Compares two ReferenceCountedObjectPointers. */
template <class ReferenceCountedObjectClass>
bool operator== (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, ReferenceCountedObjectClass* const object2)
{
return object1.getObject() == object2;
}
/** Compares two ReferenceCountedObjectPointers. */
template <class ReferenceCountedObjectClass>
bool operator== (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, const RefCountedObjectPtr<ReferenceCountedObjectClass>& object2)
{
return object1.getObject() == object2.getObject();
}
/** Compares two ReferenceCountedObjectPointers. */
template <class ReferenceCountedObjectClass>
bool operator== (ReferenceCountedObjectClass* object1, RefCountedObjectPtr<ReferenceCountedObjectClass>& object2)
{
return object1 == object2.getObject();
}
/** Compares two ReferenceCountedObjectPointers. */
template <class ReferenceCountedObjectClass>
bool operator!= (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, const ReferenceCountedObjectClass* object2)
{
return object1.getObject() != object2;
}
/** Compares two ReferenceCountedObjectPointers. */
template <class ReferenceCountedObjectClass>
bool operator!= (const RefCountedObjectPtr<ReferenceCountedObjectClass>& object1, RefCountedObjectPtr<ReferenceCountedObjectClass>& object2)
{
return object1.getObject() != object2.getObject();
}
/** Compares two ReferenceCountedObjectPointers. */
template <class ReferenceCountedObjectClass>
bool operator!= (ReferenceCountedObjectClass* object1, RefCountedObjectPtr<ReferenceCountedObjectClass>& object2)
{
return object1 != object2.getObject();
}
//==============================================================================
template <class T>
struct ContainerTraits <RefCountedObjectPtr <T> >
{
typedef T Type;
static T* get (RefCountedObjectPtr <T> const& c)
{
return c.getObject ();
}
};
//==============================================================================
} // namespace luabridge

View File

@@ -0,0 +1,244 @@
//==============================================================================
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <unordered_map>
#include "RefCountedObject.h"
namespace luabridge {
//==============================================================================
/**
Support for our RefCountedPtr.
*/
struct RefCountedPtrBase
{
// Declaration of container for the refcounts
typedef std::unordered_map <const void *, int> RefCountsType;
protected:
RefCountsType& getRefCounts () const
{
static RefCountsType refcounts;
return refcounts ;
}
};
//==============================================================================
/**
A reference counted smart pointer.
The api is compatible with boost::RefCountedPtr and std::RefCountedPtr, in the
sense that it implements a strict subset of the functionality.
This implementation uses a hash table to look up the reference count
associated with a particular pointer.
@tparam T The class type.
@todo Decompose RefCountedPtr using a policy. At a minimum, the underlying
reference count should be policy based (to support atomic operations)
and the delete behavior should be policy based (to support custom
disposal methods).
@todo Provide an intrusive version of RefCountedPtr.
*/
template <class T>
class RefCountedPtr : private RefCountedPtrBase
{
public:
template <typename Other>
struct rebind
{
typedef RefCountedPtr <Other> other;
};
/** Construct as nullptr or from existing pointer to T.
@param p The optional, existing pointer to assign from.
*/
RefCountedPtr (T* p = 0) : m_p (p)
{
++getRefCounts () [m_p];
}
/** Construct from another RefCountedPtr.
@param rhs The RefCountedPtr to assign from.
*/
RefCountedPtr (RefCountedPtr <T> const& rhs) : m_p (rhs.get())
{
++getRefCounts () [m_p];
}
/** Construct from a RefCountedPtr of a different type.
@invariant A pointer to U must be convertible to a pointer to T.
@param rhs The RefCountedPtr to assign from.
@tparam U The other object type.
*/
template <typename U>
RefCountedPtr (RefCountedPtr <U> const& rhs) : m_p (static_cast <T*> (rhs.get()))
{
++getRefCounts () [m_p];
}
/** Release the object.
If there are no more references then the object is deleted.
*/
~RefCountedPtr ()
{
reset();
}
/** Assign from another RefCountedPtr.
@param rhs The RefCountedPtr to assign from.
@return A reference to the RefCountedPtr.
*/
RefCountedPtr <T>& operator= (RefCountedPtr <T> const& rhs)
{
if (m_p != rhs.m_p)
{
reset ();
m_p = rhs.m_p;
++getRefCounts () [m_p];
}
return *this;
}
/** Assign from another RefCountedPtr of a different type.
@note A pointer to U must be convertible to a pointer to T.
@tparam U The other object type.
@param rhs The other RefCountedPtr to assign from.
@return A reference to the RefCountedPtr.
*/
template <typename U>
RefCountedPtr <T>& operator= (RefCountedPtr <U> const& rhs)
{
reset ();
m_p = static_cast <T*> (rhs.get());
++getRefCounts () [m_p];
return *this;
}
/** Retrieve the raw pointer.
@return A pointer to the object.
*/
T* get () const
{
return m_p;
}
/** Retrieve the raw pointer.
@return A pointer to the object.
*/
T* operator* () const
{
return m_p;
}
/** Retrieve the raw pointer.
@return A pointer to the object.
*/
T* operator-> () const
{
return m_p;
}
/** Determine the number of references.
@note This is not thread-safe.
@return The number of active references.
*/
long use_count () const
{
return getRefCounts () [m_p];
}
/** Release the pointer.
The reference count is decremented. If the reference count reaches
zero, the object is deleted.
*/
void reset ()
{
if (m_p != 0)
{
if (--getRefCounts () [m_p] <= 0)
delete m_p;
m_p = 0;
}
}
private:
T* m_p;
};
template <class T>
bool operator== (const RefCountedPtr <T>& lhs, const RefCountedPtr <T>& rhs)
{
return lhs.get () == rhs.get ();
}
template <class T>
bool operator!= (const RefCountedPtr <T>& lhs, const RefCountedPtr <T>& rhs)
{
return lhs.get() != rhs.get();
}
//==============================================================================
// forward declaration
template <class T>
struct ContainerTraits;
template <class T>
struct ContainerTraits <RefCountedPtr <T> >
{
typedef T Type;
static T* get (RefCountedPtr <T> const& c)
{
return c.get ();
}
};
} // namespace luabridge

View File

@@ -0,0 +1,55 @@
// https://github.com/vinniefalco/LuaBridge
//
// Copyright 2019, Dmitry Tarakanov
// SPDX-License-Identifier: MIT
#pragma once
#include <LuaBridge/detail/Stack.h>
#include <unordered_map>
namespace luabridge {
template <class K, class V>
struct Stack <std::unordered_map <K, V>>
{
typedef std::unordered_map <K, V> Map;
static void push (lua_State* L, const Map& map)
{
lua_createtable (L, 0, static_cast <int> (map.size ()));
typedef typename Map::const_iterator ConstIter;
for (ConstIter i = map.begin (); i != map.end (); ++i)
{
Stack <K>::push (L, i->first);
Stack <V>::push (L, i->second);
lua_settable (L, -3);
}
}
static Map get (lua_State* L, int index)
{
if (!lua_istable (L, index))
{
luaL_error (L, "#%d argument must be a table", index);
}
Map map;
int const absindex = lua_absindex (L, index);
lua_pushnil (L);
while (lua_next (L, absindex) != 0)
{
map.emplace (Stack <K>::get (L, -2), Stack <V>::get (L, -1));
lua_pop (L, 1);
}
return map;
}
static bool isInstance (lua_State* L, int index)
{
return lua_istable (L, index);
}
};
} // namespace luabridge

View File

@@ -0,0 +1,54 @@
// https://github.com/vinniefalco/LuaBridge
//
// Copyright 2018, Dmitry Tarakanov
// SPDX-License-Identifier: MIT
#pragma once
#include <LuaBridge/detail/Stack.h>
#include <vector>
namespace luabridge {
template <class T>
struct Stack <std::vector <T> >
{
static void push (lua_State* L, std::vector <T> const& vector)
{
lua_createtable (L, static_cast <int> (vector.size ()), 0);
for (std::size_t i = 0; i < vector.size (); ++i)
{
lua_pushinteger (L, static_cast <lua_Integer> (i + 1));
Stack <T>::push (L, vector [i]);
lua_settable (L, -3);
}
}
static std::vector <T> get (lua_State* L, int index)
{
if (!lua_istable (L, index))
{
luaL_error (L, "#%d argument must be a table", index);
}
std::vector <T> vector;
vector.reserve (static_cast <std::size_t> (get_length (L, index)));
int const absindex = lua_absindex (L, index);
lua_pushnil (L);
while (lua_next (L, absindex) != 0)
{
vector.push_back (Stack <T>::get (L, -1));
lua_pop (L, 1);
}
return vector;
}
static bool isInstance (lua_State* L, int index)
{
return lua_istable (L, index);
}
};
} // namespace luabridge

View File

@@ -0,0 +1,495 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/Config.h>
#include <LuaBridge/detail/FuncTraits.h>
#include <string>
namespace luabridge {
// We use a structure so we can define everything in the header.
//
struct CFunc
{
static void addGetter (lua_State* L, const char* name, int tableIndex)
{
assert (lua_istable (L, tableIndex));
assert (lua_iscfunction (L, -1)); // Stack: getter
lua_rawgetp (L, tableIndex, getPropgetKey ()); // Stack: getter, propget table (pg)
lua_pushvalue (L, -2); // Stack: getter, pg, getter
rawsetfield (L, -2, name); // Stack: getter, pg
lua_pop (L, 2); // Stack: -
}
static void addSetter (lua_State* L, const char* name, int tableIndex)
{
assert (lua_istable (L, tableIndex));
assert (lua_iscfunction (L, -1)); // Stack: setter
lua_rawgetp (L, tableIndex, getPropsetKey ()); // Stack: setter, propset table (ps)
lua_pushvalue (L, -2); // Stack: setter, ps, setter
rawsetfield (L, -2, name); // Stack: setter, ps
lua_pop (L, 2); // Stack: -
}
//----------------------------------------------------------------------------
/**
__index metamethod for a namespace or class static and non-static members.
Retrieves functions from metatables and properties from propget tables.
Looks through the class hierarchy if inheritance is present.
*/
static int indexMetaMethod (lua_State* L)
{
assert (lua_istable (L, 1) || lua_isuserdata (L, 1)); // Stack (further not shown): table | userdata, name
lua_getmetatable (L, 1); // Stack: class/const table (mt)
assert (lua_istable (L, -1));
for (;;)
{
lua_pushvalue (L, 2); // Stack: mt, field name
lua_rawget (L, -2); // Stack: mt, field | nil
if (lua_iscfunction (L, -1)) // Stack: mt, field
{
lua_remove (L, -2); // Stack: field
return 1;
}
assert (lua_isnil (L, -1)); // Stack: mt, nil
lua_pop (L, 1); // Stack: mt
lua_rawgetp (L, -1, getPropgetKey ()); // Stack: mt, propget table (pg)
assert (lua_istable (L, -1));
lua_pushvalue (L, 2); // Stack: mt, pg, field name
lua_rawget (L, -2); // Stack: mt, pg, getter | nil
lua_remove (L, -2); // Stack: mt, getter | nil
if (lua_iscfunction (L, -1)) // Stack: mt, getter
{
lua_remove (L, -2); // Stack: getter
lua_pushvalue (L, 1); // Stack: getter, table | userdata
lua_call (L, 1, 1); // Stack: value
return 1;
}
assert (lua_isnil (L, -1)); // Stack: mt, nil
lua_pop (L, 1); // Stack: mt
// It may mean that the field may be in const table and it's constness violation.
// Don't check that, just return nil
// Repeat the lookup in the parent metafield,
// or return nil if the field doesn't exist.
lua_rawgetp (L, -1, getParentKey ()); // Stack: mt, parent mt | nil
if (lua_isnil (L, -1)) // Stack: mt, nil
{
lua_remove (L, -2); // Stack: nil
return 1;
}
// Removethe metatable and repeat the search in the parent one.
assert (lua_istable (L, -1)); // Stack: mt, parent mt
lua_remove (L, -2); // Stack: parent mt
}
// no return
}
//----------------------------------------------------------------------------
/**
__newindex metamethod for namespace or class static members.
Retrieves properties from propset tables.
*/
static int newindexStaticMetaMethod (lua_State* L)
{
return newindexMetaMethod (L, false);
}
//----------------------------------------------------------------------------
/**
__newindex metamethod for non-static members.
Retrieves properties from propset tables.
*/
static int newindexObjectMetaMethod (lua_State* L)
{
return newindexMetaMethod (L, true);
}
static int newindexMetaMethod (lua_State* L, bool pushSelf)
{
assert (lua_istable (L, 1) || lua_isuserdata (L, 1)); // Stack (further not shown): table | userdata, name, new value
lua_getmetatable (L, 1); // Stack: metatable (mt)
assert (lua_istable (L, -1));
for (;;)
{
lua_rawgetp (L, -1, getPropsetKey ()); // Stack: mt, propset table (ps) | nil
if (lua_isnil (L, -1)) // Stack: mt, nil
{
lua_pop (L, 2); // Stack: -
return luaL_error (L, "No member named '%s'", lua_tostring (L, 2));
}
assert (lua_istable (L, -1));
lua_pushvalue (L, 2); // Stack: mt, ps, field name
lua_rawget (L, -2); // Stack: mt, ps, setter | nil
lua_remove (L, -2); // Stack: mt, setter | nil
if (lua_iscfunction (L, -1)) // Stack: mt, setter
{
lua_remove (L, -2); // Stack: setter
if (pushSelf)
{
lua_pushvalue (L, 1); // Stack: setter, table | userdata
}
lua_pushvalue (L, 3); // Stack: setter, table | userdata, new value
lua_call (L, pushSelf ? 2 : 1, 0); // Stack: -
return 0;
}
assert (lua_isnil (L, -1)); // Stack: mt, nil
lua_pop (L, 1); // Stack: mt
lua_rawgetp (L, -1, getParentKey ()); // Stack: mt, parent mt | nil
if (lua_isnil (L, -1)) // Stack: mt, nil
{
lua_pop (L, 1); // Stack: -
return luaL_error (L, "No writable member '%s'", lua_tostring (L, 2));
}
assert (lua_istable (L, -1)); // Stack: mt, parent mt
lua_remove (L, -2); // Stack: parent mt
// Repeat the search in the parent
}
// no return
}
//----------------------------------------------------------------------------
/**
lua_CFunction to report an error writing to a read-only value.
The name of the variable is in the first upvalue.
*/
static int readOnlyError (lua_State* L)
{
std::string s;
s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only";
return luaL_error (L, s.c_str ());
}
//----------------------------------------------------------------------------
/**
lua_CFunction to get a variable.
This is used for global variables or class static data members.
The pointer to the data is in the first upvalue.
*/
template <class T>
static int getVariable (lua_State* L)
{
assert (lua_islightuserdata (L, lua_upvalueindex (1)));
T const* ptr = static_cast <T const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (ptr != 0);
Stack <T>::push (L, *ptr);
return 1;
}
//----------------------------------------------------------------------------
/**
lua_CFunction to set a variable.
This is used for global variables or class static data members.
The pointer to the data is in the first upvalue.
*/
template <class T>
static int setVariable (lua_State* L)
{
assert (lua_islightuserdata (L, lua_upvalueindex (1)));
T* ptr = static_cast <T*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (ptr != 0);
*ptr = Stack <T>::get (L, 1);
return 0;
}
//----------------------------------------------------------------------------
/**
lua_CFunction to call a function with a return value.
This is used for global functions, global properties, class static methods,
and class static properties.
The function pointer (lightuserdata) in the first upvalue.
*/
template <class FnPtr>
struct Call
{
typedef typename FuncTraits <FnPtr>::Params Params;
typedef typename FuncTraits <FnPtr>::ReturnType ReturnType;
static int f (lua_State* L)
{
assert (lua_islightuserdata (L, lua_upvalueindex (1)));
FnPtr fnptr = reinterpret_cast <FnPtr> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
return Invoke <ReturnType, Params, 1>::run (L, fnptr);
}
};
//----------------------------------------------------------------------------
/**
lua_CFunction to call a class member function with a return value.
The member function pointer is in the first upvalue.
The class userdata object is at the top of the Lua stack.
*/
template <class MemFnPtr>
struct CallMember
{
typedef typename FuncTraits <MemFnPtr>::ClassType T;
typedef typename FuncTraits <MemFnPtr>::Params Params;
typedef typename FuncTraits <MemFnPtr>::ReturnType ReturnType;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
T* const t = Userdata::get <T> (L, 1, false);
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
return Invoke <ReturnType, Params, 2>::run (L, t, fnptr);
}
};
template <class MemFnPtr>
struct CallConstMember
{
typedef typename FuncTraits <MemFnPtr>::ClassType T;
typedef typename FuncTraits <MemFnPtr>::Params Params;
typedef typename FuncTraits <MemFnPtr>::ReturnType ReturnType;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
T const* const t = Userdata::get <T> (L, 1, true);
MemFnPtr const& fnptr = *static_cast <MemFnPtr const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
return Invoke <ReturnType, Params, 2>::run (L, t, fnptr);
}
};
//--------------------------------------------------------------------------
/**
lua_CFunction to call a class member lua_CFunction.
The member function pointer is in the first upvalue.
The object userdata ('this') value is at top ot the Lua stack.
*/
template <class T>
struct CallMemberCFunction
{
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
typedef int (T::*MFP) (lua_State* L);
T* const t = Userdata::get <T> (L, 1, false);
MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
return (t->*fnptr) (L);
}
};
template <class T>
struct CallConstMemberCFunction
{
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
typedef int (T::*MFP) (lua_State* L);
T const* const t = Userdata::get <T> (L, 1, true);
MFP const& fnptr = *static_cast <MFP const*> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
return (t->*fnptr) (L);
}
};
#ifdef LUABRIDGE_CXX11
//--------------------------------------------------------------------------
/**
lua_CFunction to call on a object.
The proxy function pointer (lightuserdata) is in the first upvalue.
The class userdata object is at the top of the Lua stack.
*/
template <class FnPtr>
struct CallProxyFunction
{
using Params = typename FuncTraits <FnPtr>::Params;
using ReturnType = typename FuncTraits <FnPtr>::ReturnType;
static int f (lua_State* L)
{
assert (lua_islightuserdata (L, lua_upvalueindex (1)));
auto fnptr = reinterpret_cast <FnPtr> (lua_touserdata (L, lua_upvalueindex (1)));
assert (fnptr != 0);
return Invoke <ReturnType, Params, 1>::run (L, fnptr);
}
};
template <class Functor>
struct CallProxyFunctor
{
using Params = typename FuncTraits <Functor>::Params;
using ReturnType = typename FuncTraits <Functor>::ReturnType;
static int f (lua_State* L)
{
assert (isfulluserdata (L, lua_upvalueindex (1)));
Functor& fn = *static_cast <Functor*> (lua_touserdata (L, lua_upvalueindex (1)));
return Invoke <ReturnType, Params, 1>::run (L, fn);
}
};
#endif
//--------------------------------------------------------------------------
// SFINAE Helpers
template <class MemFnPtr, bool isConst>
struct CallMemberFunctionHelper
{
static void add (lua_State* L, char const* name, MemFnPtr mf)
{
new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
lua_pushcclosure (L, &CallConstMember <MemFnPtr>::f, 1);
lua_pushvalue (L, -1);
rawsetfield (L, -5, name); // const table
rawsetfield (L, -3, name); // class table
}
};
template <class MemFnPtr>
struct CallMemberFunctionHelper <MemFnPtr, false>
{
static void add (lua_State* L, char const* name, MemFnPtr mf)
{
new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf);
lua_pushcclosure (L, &CallMember <MemFnPtr>::f, 1);
rawsetfield (L, -3, name); // class table
}
};
//--------------------------------------------------------------------------
/**
__gc metamethod for a class.
*/
template <class C>
static int gcMetaMethod (lua_State* L)
{
Userdata* const ud = Userdata::getExact <C> (L, 1);
ud->~Userdata ();
return 0;
}
/**
__gc metamethod for an arbitrary class.
*/
template <class T>
static int gcMetaMethodAny (lua_State* L)
{
assert (isfulluserdata (L, 1));
T* t = static_cast <T*> (lua_touserdata (L, 1));
t->~T ();
return 0;
}
//--------------------------------------------------------------------------
/**
lua_CFunction to get a class data member.
The pointer-to-member is in the first upvalue.
The class userdata object is at the top of the Lua stack.
*/
template <class C, typename T>
static int getProperty (lua_State* L)
{
C* const c = Userdata::get <C> (L, 1, true);
T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
try
{
Stack <T&>::push (L, c->**mp);
}
catch (const std::exception& e)
{
luaL_error (L, e.what ());
}
return 1;
}
//--------------------------------------------------------------------------
/**
lua_CFunction to set a class data member.
The pointer-to-member is in the first upvalue.
The class userdata object is at the top of the Lua stack.
*/
template <class C, typename T>
static int setProperty (lua_State* L)
{
C* const c = Userdata::get <C> (L, 1, false);
T C::** mp = static_cast <T C::**> (lua_touserdata (L, lua_upvalueindex (1)));
try
{
c->**mp = Stack <T>::get (L, 2);
}
catch (const std::exception& e)
{
luaL_error (L, e.what ());
}
return 0;
}
};
} // namespace luabridge

View File

@@ -0,0 +1,169 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
namespace luabridge {
/**
* A unique key for a type name in a metatable.
*/
inline const void* getTypeKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0x71);
#endif
}
/**
* The key of a const table in another metatable.
*/
inline const void* getConstKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0xc07);
#endif
}
/**
* The key of a class table in another metatable.
*/
inline const void* getClassKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0xc1a);
#endif
}
/**
* The key of a propget table in another metatable.
*/
inline const void* getPropgetKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0x6e7);
#endif
}
/**
* The key of a propset table in another metatable.
*/
inline const void* getPropsetKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0x5e7);
#endif
}
/**
* The key of a static table in another metatable.
*/
inline const void* getStaticKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0x57a);
#endif
}
/**
* The key of a parent table in another metatable.
*/
inline const void* getParentKey ()
{
#ifdef _NDEBUG
static char value;
return &value;
#else
return reinterpret_cast <void*> (0xdad);
#endif
}
/** Unique Lua registry keys for a class.
Each registered class inserts three keys into the registry, whose
values are the corresponding static, class, and const metatables. This
allows a quick and reliable lookup for a metatable from a template type.
*/
template <class T>
class ClassInfo
{
public:
/** Get the key for the static table.
The static table holds the static data members, static properties, and
static member functions for a class.
*/
static void const* getStaticKey ()
{
static char value;
return &value;
}
/** Get the key for the class table.
The class table holds the data members, properties, and member functions
of a class. Read-only data and properties, and const member functions are
also placed here (to save a lookup in the const table).
*/
static void const* getClassKey ()
{
static char value;
return &value;
}
/** Get the key for the const table.
The const table holds read-only data members and properties, and const
member functions of a class.
*/
static void const* getConstKey ()
{
static char value;
return &value;
}
};
} // namespace luabridge

View File

@@ -0,0 +1,10 @@
// https://github.com/vinniefalco/LuaBridge
//
// Copyright 2019, Dmitry Tarakanov
// SPDX-License-Identifier: MIT
#pragma once
#if !defined (LUABRIDGE_NO_CXX11) && (__cplusplus >= 201103L || (defined (_MSC_VER) && _MSC_VER >= 1900))
#define LUABRIDGE_CXX11
#endif

View File

@@ -0,0 +1,205 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
namespace luabridge {
/*
* Constructor generators. These templates allow you to call operator new and
* pass the contents of a type/value list to the Constructor. Like the
* function pointer containers, these are only defined up to 8 parameters.
*/
/** Constructor generators.
These templates call operator new with the contents of a type/value
list passed to the Constructor with up to 8 parameters. Two versions
of call() are provided. One performs a regular new, the other performs
a placement new.
*/
template <class T, typename List>
struct Constructor {};
template <class T>
struct Constructor <T, None>
{
static T* call (TypeListValues <None> const&)
{
return new T;
}
static T* call (void* mem, TypeListValues <None> const&)
{
return new (mem) T;
}
};
template <class T, class P1>
struct Constructor <T, TypeList <P1> >
{
static T* call (const TypeListValues<TypeList <P1> > &tvl)
{
return new T(tvl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1> > &tvl)
{
return new (mem) T(tvl.hd);
}
};
template <class T, class P1, class P2>
struct Constructor <T, TypeList <P1, TypeList <P2> > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2> > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd);
}
};
template <class T, class P1, class P2, class P3>
struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3> > > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3> > > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3> > > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
}
};
template <class T, class P1, class P2, class P3, class P4>
struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
TypeList <P4> > > > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4> > > > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4> > > > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
}
};
template <class T, class P1, class P2, class P3, class P4,
class P5>
struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
TypeList <P4, TypeList <P5> > > > > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5> > > > > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd);
}
};
template <class T, class P1, class P2, class P3, class P4,
class P5, class P6>
struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
TypeList <P4, TypeList <P5, TypeList <P6> > > > > > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd);
}
};
template <class T, class P1, class P2, class P3, class P4,
class P5, class P6, class P7>
struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
TypeList <P7> > > > > > > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
TypeList <P7> > > > > > > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.tl.hd);
}
};
template <class T, class P1, class P2, class P3, class P4,
class P5, class P6, class P7, class P8>
struct Constructor <T, TypeList <P1, TypeList <P2, TypeList <P3,
TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7,
TypeList <P8> > > > > > > > >
{
static T* call (const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
TypeList <P7, TypeList <P8> > > > > > > > > &tvl)
{
return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
}
static T* call (void* mem, const TypeListValues<TypeList <P1, TypeList <P2,
TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6,
TypeList <P7, TypeList <P8> > > > > > > > > &tvl)
{
return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
}
};
} // namespace luabridge

View File

@@ -0,0 +1,942 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2020, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/Config.h>
#ifdef LUABRIDGE_CXX11
#include <functional>
#endif
namespace luabridge {
/**
Since the throw specification is part of a function signature, the FuncTraits
family of templates needs to be specialized for both types. The
LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or
'noexcept' (if C++11 is available) to distinguish the functions.
*/
#if defined (__APPLE_CPP__) || defined (__APPLE_CC__) || defined (__clang__) || defined (__GNUC__) || \
(defined (_MSC_VER) && (_MSC_VER >= 1700))
// Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc compilers do not
// distinguish the throw specification in the function signature.
#define LUABRIDGE_THROWSPEC
#else
// Visual Studio 10 and earlier pay too much mind to useless throw () spec.
//
# define LUABRIDGE_THROWSPEC throw ()
#endif
//==============================================================================
/**
* Traits class for unrolling the type list values into function arguments.
*/
template <class ReturnType, size_t NUM_PARAMS>
struct Caller;
template <class ReturnType>
struct Caller <ReturnType, 0>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& params)
{
return fn ();
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>&)
{
return (obj->*fn) ();
}
};
template <class ReturnType>
struct Caller <ReturnType, 1>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 2>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 3>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 4>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 5>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 6>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 7>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 8>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd);
}
};
template <class ReturnType>
struct Caller <ReturnType, 9>
{
template <class Fn, class Params>
static ReturnType f (Fn& fn, TypeListValues <Params>& tvl)
{
return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd);
}
template <class T, class MemFn, class Params>
static ReturnType f (T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd,
tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd);
}
};
template <class ReturnType, class Fn, class Params>
ReturnType doCall (Fn& fn, TypeListValues <Params>& tvl)
{
return Caller <ReturnType, TypeListSize <Params>::value>::f (fn, tvl);
}
template <class ReturnType, class T, class MemFn, class Params>
static ReturnType doCall(T* obj, MemFn& fn, TypeListValues <Params>& tvl)
{
return Caller <ReturnType, TypeListSize <Params>::value>::f (obj, fn, tvl);
}
//==============================================================================
/**
Traits for function pointers.
There are three types of functions: global, non-const member, and const
member. These templates determine the type of function, which class type it
belongs to if it is a class member, the const-ness if it is a member
function, and the type information for the return value and argument list.
Expansions are provided for functions with up to 8 parameters. This can be
manually extended, or expanded to an arbitrary amount using C++11 features.
*/
template <class MemFn, class D = MemFn>
struct FuncTraits
{
};
#ifndef LUABRIDGE_CXX11
/* Ordinary function pointers. */
template <class R, class D>
struct FuncTraits <R (*) () LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef None Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class D>
struct FuncTraits <R (*) (P1) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1> Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class D>
struct FuncTraits <R (*) (P1, P2) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2> > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class D>
struct FuncTraits <R (*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class D>
struct FuncTraits <R (*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class D>
struct FuncTraits <R (*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
struct FuncTraits <R (*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
/* Windows: WINAPI (a.k.a. __stdcall) function pointers. */
#ifdef _M_IX86 // Windows 32bit only
template <class R, class D>
struct FuncTraits <R (__stdcall *) (), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef None Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class D>
struct FuncTraits <R (__stdcall *) (P1), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1> Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class D>
struct FuncTraits <R (__stdcall *) (P1, P2), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2> > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class D>
struct FuncTraits <R (__stdcall *) (P1, P2, P3), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class D>
struct FuncTraits <R (__stdcall *) (P1, P2, P3, P4), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class D>
struct FuncTraits <R (__stdcall *) (P1, P2, P3, P4, P5), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
struct FuncTraits <R (__stdcall *) (P1, P2, P3, P4, P5, P6), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
struct FuncTraits <R (__stdcall *) (P1, P2, P3, P4, P5, P6, P7), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
template <class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
struct FuncTraits <R (__stdcall *) (P1, P2, P3, P4, P5, P6, P7, P8), D>
{
static bool const isMemberFunction = false;
typedef D DeclType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
static R call (D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
#endif // _M_IX86
/* Non-const member function pointers. */
template <class T, class R, class D>
struct FuncTraits <R (T::*) () LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef None Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class D>
struct FuncTraits <R (T::*) (P1) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1> Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class D>
struct FuncTraits <R (T::*) (P1, P2) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2> > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class D>
struct FuncTraits <R (T::*) (P1, P2, P3) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
static R call (T* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
/* Const member function pointers. */
template <class T, class R, class D>
struct FuncTraits <R (T::*) () const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef None Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class D>
struct FuncTraits <R (T::*) (P1) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1> Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class D>
struct FuncTraits <R (T::*) (P1, P2) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2> > Params;
static R call (T const* obj, R (T::*fp) (P1, P2) const, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class D>
struct FuncTraits <R (T::*) (P1, P2, P3) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3> > > Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4> > > > Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5> > > > > Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6> > > > > > Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7> > > > > > > Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
template <class T, class R, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class D>
struct FuncTraits <R (T::*) (P1, P2, P3, P4, P5, P6, P7, P8) const LUABRIDGE_THROWSPEC, D>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
typedef D DeclType;
typedef T ClassType;
typedef R ReturnType;
typedef TypeList <P1, TypeList <P2, TypeList <P3, TypeList <P4, TypeList <P5, TypeList <P6, TypeList <P7, TypeList <P8> > > > > > > > Params;
static R call (T const* obj, D fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
#else // ifndef LUABRIDGE_CXX11
/* Ordinary function pointers. */
template <class R, class... ParamList>
struct FuncTraits <R (*) (ParamList...)>
{
static bool const isMemberFunction = false;
using DeclType = R (*) (ParamList...);
using ReturnType = R;
using Params = typename MakeTypeList <ParamList...>::Result;
static R call (const DeclType& fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
/* Windows: WINAPI (a.k.a. __stdcall) function pointers. */
#ifdef _M_IX86 // Windows 32bit only
template <class R, class... ParamList>
struct FuncTraits <R (__stdcall *) (ParamList...)>
{
static bool const isMemberFunction = false;
using DeclType = R (__stdcall *) (ParamList...);
using ReturnType = R;
using Params = typename MakeTypeList <ParamList...>::Result;
static R call (const DeclType& fp, TypeListValues <Params>& tvl)
{
return doCall <R> (fp, tvl);
}
};
#endif // _M_IX86
/* Non-const member function pointers. */
template <class T, class R, class... ParamList>
struct FuncTraits <R (T::*) (ParamList...)>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = false;
using DeclType = R (T::*) (ParamList...);
using ClassType = T;
using ReturnType = R;
using Params = typename MakeTypeList <ParamList...>::Result;
static R call (ClassType* obj, const DeclType& fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
/* Const member function pointers. */
template <class T, class R, class... ParamList>
struct FuncTraits <R (T::*) (ParamList...) const>
{
static bool const isMemberFunction = true;
static bool const isConstMemberFunction = true;
using DeclType = R (T::*) (ParamList...) const;
using ClassType = T;
using ReturnType = R;
using Params = typename MakeTypeList <ParamList...>::Result;
static R call (const ClassType* obj, const DeclType& fp, TypeListValues <Params>& tvl)
{
return doCall <R> (obj, fp, tvl);
}
};
/* std::function */
template <class R, class... ParamList>
struct FuncTraits <std::function <R (ParamList...)>>
{
static bool const isMemberFunction = false;
static bool const isConstMemberFunction = false;
using DeclType = std::function <R (ParamList...)>;
using ReturnType = R;
using Params = typename MakeTypeList <ParamList...>::Result;
static ReturnType call (DeclType& fn, TypeListValues <Params>& tvl)
{
return doCall <ReturnType> (fn, tvl);
}
};
#endif // ifndef LUABRIDGE_CXX11
template <class ReturnType, class Params, int startParam>
struct Invoke
{
template <class Fn>
static int run (lua_State* L, Fn& fn)
{
try
{
ArgList <Params, startParam> args (L);
Stack <ReturnType>::push (L, FuncTraits <Fn>::call (fn, args));
return 1;
}
catch (const std::exception& e)
{
return luaL_error (L, e.what ());
}
}
template <class T, class MemFn>
static int run (lua_State* L, T* object, const MemFn& fn)
{
try
{
ArgList <Params, startParam> args (L);
Stack <ReturnType>::push (L, FuncTraits <MemFn>::call (object, fn, args));
return 1;
}
catch (const std::exception& e)
{
return luaL_error (L, e.what ());
}
}
};
template <class Params, int startParam>
struct Invoke <void, Params, startParam>
{
template <class Fn>
static int run (lua_State* L, Fn& fn)
{
try
{
ArgList <Params, startParam> args (L);
FuncTraits <Fn>::call (fn, args);
return 0;
}
catch (const std::exception& e)
{
return luaL_error (L, e.what ());
}
}
template <class T, class MemFn>
static int run (lua_State* L, T* object, const MemFn& fn)
{
try
{
ArgList <Params, startParam> args (L);
FuncTraits <MemFn>::call (object, fn, args);
return 0;
}
catch (const std::exception& e)
{
return luaL_error (L, e.what ());
}
}
};
} // namespace luabridge

View File

@@ -0,0 +1,154 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2018, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/LuaRef.h>
#include <utility>
namespace luabridge {
/** Allows table iteration.
*/
class Iterator
{
lua_State* m_L;
LuaRef m_table;
LuaRef m_key;
LuaRef m_value;
void next ()
{
m_table.push ();
m_key.push ();
if (lua_next (m_L, -2))
{
m_value.pop ();
m_key.pop ();
}
else
{
m_key = Nil ();
m_value = Nil ();
}
lua_pop (m_L, 1);
}
public:
explicit Iterator (const LuaRef& table, bool isEnd = false)
: m_L (table.state ())
, m_table (table)
, m_key (table.state ()) // m_key is nil
, m_value (table.state ()) // m_value is nil
{
if (!isEnd)
{
next (); // get the first (key, value) pair from table
}
}
lua_State* state () const
{
return m_L;
}
std::pair <LuaRef, LuaRef> operator* () const
{
return std::make_pair (m_key, m_value);
}
LuaRef operator-> () const
{
return m_value;
}
bool operator!= (const Iterator& rhs) const
{
assert (m_L == rhs.m_L);
return !m_table.rawequal (rhs.m_table) || !m_key.rawequal (rhs.m_key);
}
Iterator& operator++ ()
{
if (isNil ())
{
// if the iterator reaches the end, do nothing
return *this;
}
else
{
next ();
return *this;
}
}
bool isNil () const
{
return m_key.isNil ();
}
LuaRef key () const
{
return m_key;
}
LuaRef value () const
{
return m_value;
}
private:
// Don't use postfix increment, it is less efficient
Iterator operator++ (int);
};
class Range
{
Iterator m_begin;
Iterator m_end;
public:
Range (const Iterator& begin, const Iterator& end)
: m_begin (begin)
, m_end (end)
{
}
const Iterator& begin () const { return m_begin; }
const Iterator& end () const { return m_end; }
};
inline Range pairs (const LuaRef& table)
{
return Range (Iterator (table, false), Iterator (table, true));
}
} // namespace luabridge

View File

@@ -0,0 +1,144 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <exception>
#include <string>
namespace luabridge {
class LuaException : public std::exception
{
private:
lua_State* m_L;
std::string m_what;
public:
//----------------------------------------------------------------------------
/**
Construct a LuaException after a lua_pcall().
*/
LuaException (lua_State* L, int /*code*/)
: m_L (L)
{
whatFromStack ();
}
//----------------------------------------------------------------------------
LuaException (lua_State *L,
char const*,
char const*,
long)
: m_L (L)
{
whatFromStack ();
}
//----------------------------------------------------------------------------
~LuaException() throw ()
{
}
//----------------------------------------------------------------------------
char const* what() const throw ()
{
return m_what.c_str();
}
//============================================================================
/**
Throw an exception.
This centralizes all the exceptions thrown, so that we can set
breakpoints before the stack is unwound, or otherwise customize the
behavior.
*/
template <class Exception>
static void Throw (Exception e)
{
throw e;
}
//----------------------------------------------------------------------------
/**
Wrapper for lua_pcall that throws.
*/
static void pcall (lua_State* L, int nargs = 0, int nresults = 0, int msgh = 0)
{
int code = lua_pcall (L, nargs, nresults, msgh);
if (code != LUABRIDGE_LUA_OK)
Throw (LuaException (L, code));
}
//----------------------------------------------------------------------------
/**
Initializes error handling. Subsequent Lua errors are translated to C++ exceptions.
*/
static void enableExceptions (lua_State* L)
{
lua_atpanic (L, throwAtPanic);
}
protected:
void whatFromStack ()
{
if (lua_gettop (m_L) > 0)
{
char const* s = lua_tostring (m_L, -1);
m_what = s ? s : "";
}
else
{
// stack is empty
m_what = "missing error";
}
}
private:
static int throwAtPanic (lua_State* L)
{
throw LuaException (L, -1);
}
};
//----------------------------------------------------------------------------
/**
Initializes error handling. Subsequent Lua errors are translated to C++ exceptions.
*/
static void enableExceptions (lua_State* L)
{
LuaException::enableExceptions (L);
}
} // namespace luabridge

View File

@@ -0,0 +1,151 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <cassert>
namespace luabridge {
// These are for Lua versions prior to 5.2.0.
//
#if LUA_VERSION_NUM < 502
inline int lua_absindex (lua_State* L, int idx)
{
if (idx > LUA_REGISTRYINDEX && idx < 0)
return lua_gettop (L) + idx + 1;
else
return idx;
}
inline void lua_rawgetp (lua_State* L, int idx, void const* p)
{
idx = lua_absindex (L, idx);
lua_pushlightuserdata (L, const_cast <void*> (p));
lua_rawget (L,idx);
}
inline void lua_rawsetp (lua_State* L, int idx, void const* p)
{
idx = lua_absindex (L, idx);
lua_pushlightuserdata (L, const_cast <void*> (p));
// put key behind value
lua_insert (L, -2);
lua_rawset (L, idx);
}
#define LUA_OPEQ 1
#define LUA_OPLT 2
#define LUA_OPLE 3
inline int lua_compare (lua_State* L, int idx1, int idx2, int op)
{
switch (op)
{
case LUA_OPEQ:
return lua_equal (L, idx1, idx2);
break;
case LUA_OPLT:
return lua_lessthan (L, idx1, idx2);
break;
case LUA_OPLE:
return lua_equal (L, idx1, idx2) || lua_lessthan (L, idx1, idx2);
break;
default:
return 0;
};
}
inline int get_length (lua_State* L, int idx)
{
return int (lua_objlen (L, idx));
}
#else
inline int get_length (lua_State* L, int idx)
{
lua_len (L, idx);
int len = int (luaL_checknumber (L, -1));
lua_pop (L, 1);
return len;
}
#endif
#ifndef LUA_OK
# define LUABRIDGE_LUA_OK 0
#else
# define LUABRIDGE_LUA_OK LUA_OK
#endif
/** Get a table value, bypassing metamethods.
*/
inline void rawgetfield (lua_State* L, int index, char const* key)
{
assert (lua_istable (L, index));
index = lua_absindex (L, index);
lua_pushstring (L, key);
lua_rawget (L, index);
}
/** Set a table value, bypassing metamethods.
*/
inline void rawsetfield (lua_State* L, int index, char const* key)
{
assert (lua_istable (L, index));
index = lua_absindex (L, index);
lua_pushstring (L, key);
lua_insert (L, -2);
lua_rawset (L, index);
}
/** Returns true if the value is a full userdata (not light).
*/
inline bool isfulluserdata (lua_State* L, int index)
{
return lua_isuserdata (L, index) && !lua_islightuserdata (L, index);
}
/** Test lua_State objects for global equality.
This can determine if two different lua_State objects really point
to the same global state, such as when using coroutines.
@note This is used for assertions.
*/
inline bool equalstates (lua_State* L1, lua_State* L2)
{
return lua_topointer (L1, LUA_REGISTRYINDEX) ==
lua_topointer (L2, LUA_REGISTRYINDEX);
}
} // namespace luabridge

View File

@@ -0,0 +1,1051 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2018, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2008, Nigel Atkinson <suprapilot+LuaCode@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/LuaException.h>
#include <LuaBridge/detail/Stack.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
namespace luabridge {
//------------------------------------------------------------------------------
/**
Type tag for representing LUA_TNIL.
Construct one of these using `Nil ()` to represent a Lua nil. This is faster
than creating a reference in the registry to nil. Example:
LuaRef t (LuaRef::createTable (L));
...
t ["k"] = Nil (); // assign nil
*/
struct Nil
{
};
//------------------------------------------------------------------------------
/**
Stack specialization for Nil.
*/
template <>
struct Stack <Nil>
{
static void push (lua_State* L, Nil)
{
lua_pushnil (L);
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TTABLE;
}
};
/**
* Base class for LuaRef and table value proxy classes.
*/
template <class Impl, class LuaRef>
class LuaRefBase
{
protected:
//----------------------------------------------------------------------------
/**
Pop the Lua stack.
Pops the specified number of stack items on destruction. We use this
when returning objects, to avoid an explicit temporary variable, since
the destructor executes after the return statement. For example:
template <class U>
U cast (lua_State* L)
{
StackPop p (L, 1);
...
return U (); // dtor called after this line
}
@note The `StackPop` object must always be a named local variable.
*/
class StackPop
{
public:
/** Create a StackPop object.
@param count The number of stack entries to pop on destruction.
*/
StackPop (lua_State* L, int count)
: m_L (L)
, m_count (count)
{
}
~StackPop ()
{
lua_pop (m_L, m_count);
}
private:
lua_State* m_L;
int m_count;
};
friend struct Stack <LuaRef>;
//----------------------------------------------------------------------------
/**
Type tag for stack construction.
*/
struct FromStack { };
LuaRefBase (lua_State* L)
: m_L (L)
{
}
//----------------------------------------------------------------------------
/**
Create a reference to this ref.
This is used internally.
*/
int createRef () const
{
impl ().push ();
return luaL_ref (m_L, LUA_REGISTRYINDEX);
}
public:
//----------------------------------------------------------------------------
/**
converts to a string using luas tostring function
*/
std::string tostring () const
{
lua_getglobal (m_L, "tostring");
impl ().push ();
lua_call (m_L, 1, 1);
const char* str = lua_tostring (m_L, -1);
lua_pop (m_L, 1);
return str;
}
//----------------------------------------------------------------------------
/**
Print a text description of the value to a stream.
This is used for diagnostics.
*/
void print (std::ostream& os) const
{
switch (type ())
{
case LUA_TNIL:
os << "nil";
break;
case LUA_TNUMBER:
os << cast <lua_Number> ();
break;
case LUA_TBOOLEAN:
os << (cast <bool> () ? "true" : "false");
break;
case LUA_TSTRING:
os << '"' << cast <std::string> () << '"';
break;
case LUA_TTABLE:
os << "table: " << tostring ();
break;
case LUA_TFUNCTION:
os << "function: " << tostring ();
break;
case LUA_TUSERDATA:
os << "userdata: " << tostring ();
break;
case LUA_TTHREAD:
os << "thread: " << tostring ();
break;
case LUA_TLIGHTUSERDATA:
os << "lightuserdata: " << tostring ();
break;
default:
os << "unknown";
break;
}
}
//------------------------------------------------------------------------------
/**
Write a LuaRef to a stream.
This allows LuaRef and table proxies to work with streams.
*/
friend std::ostream& operator<< (std::ostream& os, LuaRefBase const& ref)
{
ref.print (os);
return os;
}
//============================================================================
//
// This group of member functions is mirrored in Proxy
//
/** Retrieve the lua_State associated with the reference.
*/
lua_State* state () const
{
return m_L;
}
//----------------------------------------------------------------------------
/**
Place the object onto the Lua stack.
*/
void push (lua_State* L) const
{
assert (equalstates (L, m_L));
(void) L;
impl ().push ();
}
//----------------------------------------------------------------------------
/**
Pop the top of Lua stack and assign the ref to m_ref
*/
void pop (lua_State* L)
{
assert (equalstates (L, m_L));
(void) L;
impl ().pop ();
}
//----------------------------------------------------------------------------
/**
Determine the object type.
The return values are the same as for `lua_type`.
*/
/** @{ */
int type () const
{
impl ().push ();
StackPop p (m_L, 1);
return lua_type (m_L, -1);
}
// should never happen
// bool isNone () const { return m_ref == LUA_NOREF; }
bool isNil () const { return type () == LUA_TNIL; }
bool isBool () const { return type () == LUA_TBOOLEAN; }
bool isNumber () const { return type () == LUA_TNUMBER; }
bool isString () const { return type () == LUA_TSTRING; }
bool isTable () const { return type () == LUA_TTABLE; }
bool isFunction () const { return type () == LUA_TFUNCTION; }
bool isUserdata () const { return type () == LUA_TUSERDATA; }
bool isThread () const { return type () == LUA_TTHREAD; }
bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; }
/** @} */
//----------------------------------------------------------------------------
/**
Perform an explicit conversion.
*/
template <class T>
T cast () const
{
StackPop p (m_L, 1);
impl ().push ();
return Stack <T>::get (m_L, -1);
}
//----------------------------------------------------------------------------
/**
Type check
*/
template <class T>
bool isInstance () const
{
StackPop p (m_L, 1);
impl ().push ();
return Stack <T>::isInstance (m_L, -1);
}
//----------------------------------------------------------------------------
/**
Universal implicit conversion operator.
NOTE: Visual Studio 2010 and 2012 have a bug where this function
is not used. See:
http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014
https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile
// This code snippet fails to compile in vs2010,vs2012
struct S {
template <class T> operator T () const { return T (); }
};
int main () {
S () || false;
return 0;
}
*/
template <class T>
operator T () const
{
return cast <T> ();
}
//----------------------------------------------------------------------------
/**
Universal comparison operators.
*/
/** @{ */
template <class T>
bool operator== (T rhs) const
{
StackPop p (m_L, 2);
impl ().push ();
Stack <T>::push (m_L, rhs);
return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1;
}
template <class T>
bool operator< (T rhs) const
{
StackPop p (m_L, 2);
impl ().push ();;
Stack <T>::push (m_L, rhs);
int lhsType = lua_type (m_L, -2);
int rhsType = lua_type (m_L, -1);
if (lhsType != rhsType)
{
return lhsType < rhsType;
}
return lua_compare (m_L, -2, -1, LUA_OPLT) == 1;
}
template <class T>
bool operator<= (T rhs) const
{
StackPop p (m_L, 2);
impl ().push ();;
Stack <T>::push (m_L, rhs);
int lhsType = lua_type (m_L, -2);
int rhsType = lua_type (m_L, -1);
if (lhsType != rhsType)
{
return lhsType <= rhsType;
}
return lua_compare (m_L, -2, -1, LUA_OPLE) == 1;
}
template <class T>
bool operator> (T rhs) const
{
StackPop p (m_L, 2);
impl ().push ();;
Stack <T>::push (m_L, rhs);
int lhsType = lua_type (m_L, -2);
int rhsType = lua_type (m_L, -1);
if (lhsType != rhsType)
{
return lhsType > rhsType;
}
return lua_compare (m_L, -1, -2, LUA_OPLT) == 1;
}
template <class T>
bool operator>= (T rhs) const
{
StackPop p (m_L, 2);
impl ().push ();;
Stack <T>::push (m_L, rhs);
int lhsType = lua_type (m_L, -2);
int rhsType = lua_type (m_L, -1);
if (lhsType != rhsType)
{
return lhsType >= rhsType;
}
return lua_compare (m_L, -1, -2, LUA_OPLE) == 1;
}
template <class T>
bool rawequal (T rhs) const
{
StackPop p (m_L, 2);
impl ().push ();;
Stack <T>::push (m_L, rhs);
return lua_rawequal (m_L, -1, -2) == 1;
}
/** @} */
//----------------------------------------------------------------------------
/**
Append a value to the table.
If the table is a sequence this will add another element to it.
*/
template <class T>
void append (T v) const
{
impl ().push ();;
Stack <T>::push (m_L, v);
luaL_ref (m_L, -2);
lua_pop (m_L, 1);
}
//----------------------------------------------------------------------------
/**
Call the length operator.
This is identical to applying the Lua # operator.
*/
int length () const
{
StackPop p (m_L, 1);
impl ().push ();;
return get_length (m_L, -1);
}
//----------------------------------------------------------------------------
/**
Call Lua code.
These overloads allow Lua code to be called with up to 8 parameters.
The return value is provided as a LuaRef (which may be LUA_REFNIL).
If an error occurs, a LuaException is thrown.
*/
/** @{ */
LuaRef operator() () const
{
impl ().push ();;
LuaException::pcall (m_L, 0, 1);
return LuaRef::fromStack (m_L);
}
template <class P1>
LuaRef operator() (P1 p1) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
LuaException::pcall (m_L, 1, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2>
LuaRef operator() (P1 p1, P2 p2) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
LuaException::pcall (m_L, 2, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2, class P3>
LuaRef operator() (P1 p1, P2 p2, P3 p3) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
Stack <P3>::push (m_L, p3);
LuaException::pcall (m_L, 3, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2, class P3, class P4>
LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
Stack <P3>::push (m_L, p3);
Stack <P4>::push (m_L, p4);
LuaException::pcall (m_L, 4, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2, class P3, class P4, class P5>
LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
Stack <P3>::push (m_L, p3);
Stack <P4>::push (m_L, p4);
Stack <P5>::push (m_L, p5);
LuaException::pcall (m_L, 5, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2, class P3, class P4, class P5, class P6>
LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
Stack <P3>::push (m_L, p3);
Stack <P4>::push (m_L, p4);
Stack <P5>::push (m_L, p5);
Stack <P6>::push (m_L, p6);
LuaException::pcall (m_L, 6, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2, class P3, class P4, class P5, class P6, class P7>
LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
{
impl ().push ();;
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
Stack <P3>::push (m_L, p3);
Stack <P4>::push (m_L, p4);
Stack <P5>::push (m_L, p5);
Stack <P6>::push (m_L, p6);
Stack <P7>::push (m_L, p7);
LuaException::pcall (m_L, 7, 1);
return LuaRef::fromStack (m_L);
}
template <class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
{
impl ().push ();
Stack <P1>::push (m_L, p1);
Stack <P2>::push (m_L, p2);
Stack <P3>::push (m_L, p3);
Stack <P4>::push (m_L, p4);
Stack <P5>::push (m_L, p5);
Stack <P6>::push (m_L, p6);
Stack <P7>::push (m_L, p7);
Stack <P8>::push (m_L, p8);
LuaException::pcall (m_L, 8, 1);
return LuaRef::fromStack (m_L);
}
/** @} */
//============================================================================
protected:
lua_State* m_L;
private:
const Impl& impl () const
{
return static_cast <const Impl&> (*this);
}
Impl& impl ()
{
return static_cast <Impl&> (*this);
}
};
//------------------------------------------------------------------------------
/**
Lightweight reference to a Lua object.
The reference is maintained for the lifetime of the C++ object.
*/
class LuaRef : public LuaRefBase <LuaRef, LuaRef>
{
//----------------------------------------------------------------------------
/**
A proxy for representing table values.
*/
class Proxy : public LuaRefBase <Proxy, LuaRef>
{
friend class LuaRef;
public:
//--------------------------------------------------------------------------
/**
Construct a Proxy from a table value.
The table is in the registry, and the key is at the top of the stack.
The key is popped off the stack.
*/
Proxy (lua_State* L, int tableRef)
: LuaRefBase (L)
, m_tableRef (LUA_NOREF)
, m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX))
{
lua_rawgeti (m_L, LUA_REGISTRYINDEX, tableRef);
m_tableRef = luaL_ref (L, LUA_REGISTRYINDEX);
}
//--------------------------------------------------------------------------
/**
Create a Proxy via copy constructor.
It is best to avoid code paths that invoke this, because it creates
an extra temporary Lua reference. Typically this is done by passing
the Proxy parameter as a `const` reference.
*/
Proxy (Proxy const& other)
: LuaRefBase (other.m_L)
, m_tableRef (LUA_NOREF)
, m_keyRef (LUA_NOREF)
{
lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_tableRef);
m_tableRef = luaL_ref (m_L, LUA_REGISTRYINDEX);
lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef);
m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX);
}
//--------------------------------------------------------------------------
/**
Destroy the proxy.
This does not destroy the table value.
*/
~Proxy ()
{
luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef);
luaL_unref (m_L, LUA_REGISTRYINDEX, m_tableRef);
}
//--------------------------------------------------------------------------
/**
Assign a new value to this table key.
This may invoke metamethods.
*/
template <class T>
Proxy& operator= (T v)
{
StackPop p (m_L, 1);
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
Stack <T>::push (m_L, v);
lua_settable (m_L, -3);
return *this;
}
//--------------------------------------------------------------------------
/**
Assign a new value to this table key.
The assignment is raw, no metamethods are invoked.
*/
template <class T>
Proxy& rawset (T v)
{
StackPop p (m_L, 1);
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
Stack <T>::push (m_L, v);
lua_rawset (m_L, -3);
return *this;
}
//--------------------------------------------------------------------------
/**
Push the value onto the Lua stack.
*/
using LuaRefBase::push;
void push () const
{
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef);
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef);
lua_gettable (m_L, -2);
lua_remove (m_L, -2); // remove the table
}
//--------------------------------------------------------------------------
/**
Access a table value using a key.
This invokes metamethods.
*/
template <class T>
Proxy operator[] (T key) const
{
return LuaRef (*this) [key];
}
//--------------------------------------------------------------------------
/**
Access a table value using a key.
The operation is raw, metamethods are not invoked. The result is
passed by value and may not be modified.
*/
template <class T>
LuaRef rawget (T key) const
{
return LuaRef (*this).rawget (key);
}
private:
int m_tableRef;
int m_keyRef;
};
friend struct Stack <Proxy>;
friend struct Stack <Proxy&>;
//----------------------------------------------------------------------------
/**
Create a reference to an object at the top of the Lua stack and pop it.
This constructor is private and not invoked directly.
Instead, use the `fromStack` function.
@note The object is popped.
*/
LuaRef (lua_State* L, FromStack)
: LuaRefBase (L)
, m_ref (luaL_ref (m_L, LUA_REGISTRYINDEX))
{
}
//----------------------------------------------------------------------------
/**
Create a reference to an object on the Lua stack.
This constructor is private and not invoked directly.
Instead, use the `fromStack` function.
@note The object is not popped.
*/
LuaRef (lua_State* L, int index, FromStack)
: LuaRefBase (L)
, m_ref (LUA_NOREF)
{
lua_pushvalue (m_L, index);
m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
}
public:
//----------------------------------------------------------------------------
/**
Create a nil reference.
The LuaRef may be assigned later.
*/
LuaRef (lua_State* L)
: LuaRefBase (L)
, m_ref (LUA_NOREF)
{
}
//----------------------------------------------------------------------------
/**
Create a reference to a value.
*/
template <class T>
LuaRef (lua_State* L, T v)
: LuaRefBase (L)
, m_ref (LUA_NOREF)
{
Stack <T>::push (m_L, v);
m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
}
//----------------------------------------------------------------------------
/**
Create a reference to a table value.
*/
LuaRef (Proxy const& v)
: LuaRefBase (v.state ())
, m_ref (v.createRef ())
{
}
//----------------------------------------------------------------------------
/**
Create a new reference to an existing reference.
*/
LuaRef (LuaRef const& other)
: LuaRefBase (other.m_L)
, m_ref (other.createRef ())
{
}
//----------------------------------------------------------------------------
/**
Destroy a reference.
The corresponding Lua registry reference will be released.
@note If the state refers to a thread, it is the responsibility of the
caller to ensure that the thread still exists when the LuaRef
is destroyed.
*/
~LuaRef ()
{
luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
}
//----------------------------------------------------------------------------
/**
Return a LuaRef from a top stack item.
The stack item is not popped.
*/
static LuaRef fromStack (lua_State* L)
{
return LuaRef (L, FromStack ());
}
//----------------------------------------------------------------------------
/**
Return a LuaRef from a stack item.
The stack item is not popped.
*/
static LuaRef fromStack (lua_State* L, int index)
{
lua_pushvalue (L, index);
return LuaRef (L, FromStack ());
}
//----------------------------------------------------------------------------
/**
Create a new empty table and return a reference to it.
It is also possible to use the free function `newTable`.
@see ::luabridge::newTable
*/
static LuaRef newTable (lua_State* L)
{
lua_newtable (L);
return LuaRef (L, FromStack ());
}
//----------------------------------------------------------------------------
/**
Return a reference to a named global.
It is also possible to use the free function `getGlobal`.
@see ::luabridge::getGlobal
*/
static LuaRef getGlobal (lua_State *L, char const* name)
{
lua_getglobal (L, name);
return LuaRef (L, FromStack ());
}
//----------------------------------------------------------------------------
/**
Assign another LuaRef to this LuaRef.
*/
LuaRef& operator= (LuaRef const& rhs)
{
LuaRef ref (rhs);
swap (ref);
return *this;
}
//----------------------------------------------------------------------------
/**
Assign Proxy to this LuaRef.
*/
LuaRef& operator= (LuaRef::Proxy const& rhs)
{
LuaRef ref (rhs);
swap (ref);
return *this;
}
//----------------------------------------------------------------------------
/**
Assign nil to this LuaRef.
*/
LuaRef& operator= (Nil const&)
{
LuaRef ref (m_L);
swap (ref);
return *this;
}
//----------------------------------------------------------------------------
/**
Assign a different value to this LuaRef.
*/
template <class T>
LuaRef& operator= (T rhs)
{
LuaRef ref (m_L, rhs);
swap (ref);
return *this;
}
//----------------------------------------------------------------------------
/**
Place the object onto the Lua stack.
*/
using LuaRefBase::push;
void push () const
{
lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_ref);
}
//----------------------------------------------------------------------------
/**
Pop the top of Lua stack and assign the ref to m_ref
*/
void pop ()
{
luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref);
m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX);
}
//----------------------------------------------------------------------------
/**
Access a table value using a key.
This invokes metamethods.
*/
template <class T>
Proxy operator[] (T key) const
{
Stack <T>::push (m_L, key);
return Proxy (m_L, m_ref);
}
//--------------------------------------------------------------------------
/**
Access a table value using a key.
The operation is raw, metamethods are not invoked. The result is
passed by value and may not be modified.
*/
template <class T>
LuaRef rawget (T key) const
{
StackPop (m_L, 1);
push (m_L);
Stack <T>::push (m_L, key);
lua_rawget (m_L, -2);
return LuaRef (m_L, FromStack ());
}
private:
void swap (LuaRef& other)
{
std::swap (m_L, other.m_L);
std::swap (m_ref, other.m_ref);
}
int m_ref;
};
//------------------------------------------------------------------------------
/**
* Stack specialization for `LuaRef`.
*/
template <>
struct Stack <LuaRef>
{
// The value is const& to prevent a copy construction.
//
static void push (lua_State* L, LuaRef const& v)
{
v.push (L);
}
static LuaRef get (lua_State* L, int index)
{
return LuaRef::fromStack (L, index);
}
};
//------------------------------------------------------------------------------
/**
* Stack specialization for `Proxy`.
*/
template <>
struct Stack <LuaRef::Proxy>
{
// The value is const& to prevent a copy construction.
//
static void push (lua_State* L, LuaRef::Proxy const& v)
{
v.push (L);
}
};
//------------------------------------------------------------------------------
/**
Create a reference to a new, empty table.
This is a syntactic abbreviation for LuaRef::newTable ().
*/
inline LuaRef newTable (lua_State* L)
{
return LuaRef::newTable (L);
}
//------------------------------------------------------------------------------
/**
Create a reference to a value in the global table.
This is a syntactic abbreviation for LuaRef::getGlobal ().
*/
inline LuaRef getGlobal (lua_State *L, char const* name)
{
return LuaRef::getGlobal (L, name);
}
//------------------------------------------------------------------------------
// more C++-like cast syntax
//
template <class T>
T LuaRef_cast (LuaRef const& lr)
{
return lr.cast <T> ();
}
} // namespace luabridge

View File

@@ -0,0 +1,1252 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/Config.h>
#include <LuaBridge/detail/ClassInfo.h>
#include <LuaBridge/detail/LuaException.h>
#include <LuaBridge/detail/Security.h>
#include <LuaBridge/detail/TypeTraits.h>
#include <stdexcept>
#include <string>
namespace luabridge {
namespace detail {
/**
* Base for class and namespace registration.
* Maintains Lua stack in the proper state.
* Once beginNamespace, beginClass or deriveClass is called the parent
* object upon its destruction may no longer clear the Lua stack.
* Then endNamespace or endClass is called, a new parent is created
* and the child transfers the responsibility for clearing stack to it.
* So there can be maximum one "active" registrar object.
*/
class Registrar
{
protected:
lua_State* const L;
int mutable m_stackSize;
Registrar (lua_State* L)
: L (L)
, m_stackSize (0)
{
}
Registrar (const Registrar& rhs)
: L (rhs.L)
, m_stackSize (rhs.m_stackSize)
{
rhs.m_stackSize = 0;
}
#ifndef _MSC_VER
// MS compiler thinks it's the 2nd copy ctor
Registrar(Registrar& rhs)
: L (rhs.L)
, m_stackSize (rhs.m_stackSize)
{
rhs.m_stackSize = 0;
}
#endif // ifndef _MSC_VER
Registrar& operator= (const Registrar& rhs)
{
Registrar tmp (rhs);
std::swap (m_stackSize, tmp.m_stackSize);
return *this;
}
~Registrar ()
{
if (m_stackSize > 0)
{
assert (m_stackSize <= lua_gettop (L));
lua_pop (L, m_stackSize);
}
}
void assertIsActive () const
{
if (m_stackSize == 0)
{
throw std::logic_error ("Unable to continue registration");
}
}
};
} // namespace detail
/** Provides C++ to Lua registration capabilities.
This class is not instantiated directly, call `getGlobalNamespace` to start
the registration process.
*/
class Namespace : public detail::Registrar
{
//============================================================================
/**
Error reporting.
VF: This function looks handy, why aren't we using it?
*/
#if 0
static int luaError (lua_State* L, std::string message)
{
assert (lua_isstring (L, lua_upvalueindex (1)));
std::string s;
// Get information on the caller's caller to format the message,
// so the error appears to originate from the Lua source.
lua_Debug ar;
int result = lua_getstack (L, 2, &ar);
if (result != 0)
{
lua_getinfo (L, "Sl", &ar);
s = ar.short_src;
if (ar.currentline != -1)
{
// poor mans int to string to avoid <strstrream>.
lua_pushnumber (L, ar.currentline);
s = s + ":" + lua_tostring (L, -1) + ": ";
lua_pop (L, 1);
}
}
s = s + message;
return luaL_error (L, s.c_str ());
}
#endif
/**
Factored base to reduce template instantiations.
*/
class ClassBase : public detail::Registrar
{
public:
explicit ClassBase (Namespace& parent)
: Registrar (parent)
{
}
using Registrar::operator=;
protected:
//--------------------------------------------------------------------------
/**
Create the const table.
*/
void createConstTable (const char* name, bool trueConst = true)
{
std::string type_name = std::string (trueConst ? "const " : "") + name;
// Stack: namespace table (ns)
lua_newtable (L); // Stack: ns, const table (co)
lua_pushvalue (L, -1); // Stack: ns, co, co
lua_setmetatable (L, -2); // co.__metatable = co. Stack: ns, co
lua_pushstring (L, type_name.c_str ());
lua_rawsetp (L, -2, getTypeKey ()); // co [typeKey] = name. Stack: ns, co
lua_pushcfunction (L, &CFunc::indexMetaMethod);
rawsetfield (L, -2, "__index");
lua_pushcfunction (L, &CFunc::newindexObjectMetaMethod);
rawsetfield (L, -2, "__newindex");
lua_newtable (L);
lua_rawsetp (L, -2, getPropgetKey ());
if (Security::hideMetatables ())
{
lua_pushnil (L);
rawsetfield (L, -2, "__metatable");
}
}
//--------------------------------------------------------------------------
/**
Create the class table.
The Lua stack should have the const table on top.
*/
void createClassTable (char const* name)
{
// Stack: namespace table (ns), const table (co)
// Class table is the same as const table except the propset table
createConstTable (name, false); // Stack: ns, co, cl
lua_newtable (L); // Stack: ns, co, cl, propset table (ps)
lua_rawsetp (L, -2, getPropsetKey ()); // cl [propsetKey] = ps. Stack: ns, co, cl
lua_pushvalue (L, -2); // Stack: ns, co, cl, co
lua_rawsetp(L, -2, getConstKey ()); // cl [constKey] = co. Stack: ns, co, cl
lua_pushvalue (L, -1); // Stack: ns, co, cl, cl
lua_rawsetp (L, -3, getClassKey ()); // co [classKey] = cl. Stack: ns, co, cl
}
//--------------------------------------------------------------------------
/**
Create the static table.
*/
void createStaticTable (char const* name)
{
// Stack: namespace table (ns), const table (co), class table (cl)
lua_newtable (L); // Stack: ns, co, cl, visible static table (vst)
lua_newtable (L); // Stack: ns, co, cl, st, static metatable (st)
lua_pushvalue (L, -1); // Stack: ns, co, cl, vst, st, st
lua_setmetatable (L, -3); // st.__metatable = mt. Stack: ns, co, cl, vst, st
lua_insert (L, -2); // Stack: ns, co, cl, st, vst
rawsetfield (L, -5, name); // ns [name] = vst. Stack: ns, co, cl, st
#if 0
lua_pushlightuserdata (L, this);
lua_pushcclosure (L, &tostringMetaMethod, 1);
rawsetfield (L, -2, "__tostring");
#endif
lua_pushcfunction (L, &CFunc::indexMetaMethod);
rawsetfield (L, -2, "__index");
lua_pushcfunction (L, &CFunc::newindexStaticMetaMethod);
rawsetfield (L, -2, "__newindex");
lua_newtable (L); // Stack: ns, co, cl, st, proget table (pg)
lua_rawsetp (L, -2, getPropgetKey ()); // st [propgetKey] = pg. Stack: ns, co, cl, st
lua_newtable (L); // Stack: ns, co, cl, st, propset table (ps)
lua_rawsetp (L, -2, getPropsetKey ()); // st [propsetKey] = pg. Stack: ns, co, cl, st
lua_pushvalue (L, -2); // Stack: ns, co, cl, st, cl
lua_rawsetp(L, -2, getClassKey()); // st [classKey] = cl. Stack: ns, co, cl, st
if (Security::hideMetatables ())
{
lua_pushnil (L);
rawsetfield (L, -2, "__metatable");
}
}
//==========================================================================
/**
lua_CFunction to construct a class object wrapped in a container.
*/
template <class Params, class C>
static int ctorContainerProxy (lua_State* L)
{
typedef typename ContainerTraits <C>::Type T;
ArgList <Params, 2> args (L);
T* const p = Constructor <T, Params>::call (args);
UserdataSharedHelper <C, false>::push (L, p);
return 1;
}
//--------------------------------------------------------------------------
/**
lua_CFunction to construct a class object in-place in the userdata.
*/
template <class Params, class T>
static int ctorPlacementProxy (lua_State* L)
{
ArgList <Params, 2> args (L);
UserdataValue <T>* value = UserdataValue <T>::place (L);
Constructor <T, Params>::call (value->getObject (), args);
value->commit ();
return 1;
}
void assertStackState () const
{
// Stack: const table (co), class table (cl), static table (st)
assert (lua_istable (L, -3));
assert (lua_istable (L, -2));
assert (lua_istable (L, -1));
}
};
//============================================================================
//
// Class
//
//============================================================================
/**
Provides a class registration in a lua_State.
After construction the Lua stack holds these objects:
-1 static table
-2 class table
-3 const table
-4 enclosing namespace table
*/
template <class T>
class Class : public ClassBase
{
public:
//==========================================================================
/**
Register a new class or add to an existing class registration.
*/
Class (char const* name, Namespace& parent)
: ClassBase (parent)
{
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
rawgetfield (L, -1, name); // Stack: ns, static table (st) | nil
if (lua_isnil (L, -1)) // Stack: ns, nil
{
lua_pop (L, 1); // Stack: ns
createConstTable (name); // Stack: ns, const table (co)
lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); // Stack: ns, co, function
rawsetfield (L, -2, "__gc"); // co ["__gc"] = function. Stack: ns, co
++m_stackSize;
createClassTable (name); // Stack: ns, co, class table (cl)
lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); // Stack: ns, co, cl, function
rawsetfield (L, -2, "__gc"); // cl ["__gc"] = function. Stack: ns, co, cl
++m_stackSize;
createStaticTable (name); // Stack: ns, co, cl, st
++m_stackSize;
// Map T back to its tables.
lua_pushvalue (L, -1); // Stack: ns, co, cl, st, st
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ()); // Stack: ns, co, cl, st
lua_pushvalue (L, -2); // Stack: ns, co, cl, st, cl
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); // Stack: ns, co, cl, st
lua_pushvalue (L, -3); // Stack: ns, co, cl, st, co
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); // Stack: ns, co, cl, st
}
else
{
assert (lua_istable (L, -1)); // Stack: ns, st
++m_stackSize;
// Map T back from its stored tables
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); // Stack: ns, st, co
lua_insert (L, -2); // Stack: ns, co, st
++m_stackSize;
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); // Stack: ns, co, st, cl
lua_insert (L, -2); // Stack: ns, co, cl, st
++m_stackSize;
}
}
//==========================================================================
/**
Derive a new class.
*/
Class (char const* name, Namespace& parent, void const* const staticKey)
: ClassBase (parent)
{
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
createConstTable (name); // Stack: ns, const table (co)
lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); // Stack: ns, co, function
rawsetfield (L, -2, "__gc"); // co ["__gc"] = function. Stack: ns, co
++m_stackSize;
createClassTable (name); // Stack: ns, co, class table (cl)
lua_pushcfunction (L, &CFunc::gcMetaMethod <T>); // Stack: ns, co, cl, function
rawsetfield (L, -2, "__gc"); // cl ["__gc"] = function. Stack: ns, co, cl
++m_stackSize;
createStaticTable (name); // Stack: ns, co, cl, st
++m_stackSize;
lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey); // Stack: ns, co, cl, st, parent st (pst) | nil
if (lua_isnil (L, -1)) // Stack: ns, co, cl, st, nil
{
++m_stackSize;
throw std::runtime_error ("Base class is not registered");
}
assert (lua_istable (L, -1)); // Stack: ns, co, cl, st, pst
lua_rawgetp (L, -1, getClassKey ()); // Stack: ns, co, cl, st, pst, parent cl (pcl)
assert (lua_istable (L, -1));
lua_rawgetp (L, -1, getConstKey ()); // Stack: ns, co, cl, st, pst, pcl, parent co (pco)
assert (lua_istable (L, -1));
lua_rawsetp (L, -6, getParentKey ()); // co [parentKey] = pco. Stack: ns, co, cl, st, pst, pcl
lua_rawsetp (L, -4, getParentKey ()); // cl [parentKey] = pcl. Stack: ns, co, cl, st, pst
lua_rawsetp (L, -2, getParentKey ()); // st [parentKey] = pst. Stack: ns, co, cl, st
lua_pushvalue (L, -1); // Stack: ns, co, cl, st, st
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getStaticKey ()); // Stack: ns, co, cl, st
lua_pushvalue (L, -2); // Stack: ns, co, cl, st, cl
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ()); // Stack: ns, co, cl, st
lua_pushvalue (L, -3); // Stack: ns, co, cl, st, co
lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ()); // Stack: ns, co, cl, st
}
//--------------------------------------------------------------------------
/**
Continue registration in the enclosing namespace.
*/
Namespace endClass ()
{
assert (m_stackSize > 3);
m_stackSize -= 3;
lua_pop (L, 3);
return Namespace (*this);
}
//--------------------------------------------------------------------------
/**
Add or replace a static data member.
*/
template <class U>
Class <T>& addStaticProperty (char const* name, U* pu, bool isWritable = true)
{
return addStaticData (name, pu, isWritable);
}
//--------------------------------------------------------------------------
/**
Add or replace a static data member.
*/
template <class U>
Class <T>& addStaticData (char const* name, U* pu, bool isWritable = true)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushlightuserdata (L, pu); // Stack: co, cl, st, pointer
lua_pushcclosure (L, &CFunc::getVariable <U>, 1); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -2); // Stack: co, cl, st
if (isWritable)
{
lua_pushlightuserdata (L, pu); // Stack: co, cl, st, ps, pointer
lua_pushcclosure (L, &CFunc::setVariable <U>, 1); // Stack: co, cl, st, ps, setter
}
else
{
lua_pushstring (L, name); // Stack: co, cl, st, name
lua_pushcclosure (L, &CFunc::readOnlyError, 1); // Stack: co, cl, st, error_fn
}
CFunc::addSetter (L, name, -2); // Stack: co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a static property member.
If the set function is null, the property is read-only.
*/
template <class U>
Class <T>& addStaticProperty (char const* name, U (*get) (), void (*set) (U) = 0)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushlightuserdata (L, reinterpret_cast <void*> (get)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::Call <U (*) ()>::f, 1); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -2); // Stack: co, cl, st
if (set != 0)
{
lua_pushlightuserdata (L, reinterpret_cast <void*> (set)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::Call <void (*) (U)>::f, 1); // Stack: co, cl, st, setter
}
else
{
lua_pushstring (L, name); // Stack: co, cl, st, ps, name
lua_pushcclosure (L, &CFunc::readOnlyError, 1); // Stack: co, cl, st, error_fn
}
CFunc::addSetter (L, name, -2); // Stack: co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a static member function.
*/
template <class FP>
Class <T>& addStaticFunction (char const* name, FP const fp)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushlightuserdata (L, reinterpret_cast <void*> (fp)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::Call <FP>::f, 1); // co, cl, st, function
rawsetfield (L, -2, name); // co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a lua_CFunction.
*/
Class <T>& addStaticFunction (char const* name, int (*const fp) (lua_State*))
{
return addStaticCFunction (name, fp);
}
//--------------------------------------------------------------------------
/**
Add or replace a lua_CFunction.
*/
Class <T>& addStaticCFunction (char const* name, int (*const fp) (lua_State*))
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushcfunction (L, fp); // co, cl, st, function
rawsetfield (L, -2, name); // co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a data member.
*/
template <class U>
Class <T>& addProperty (char const* name, U T::* mp, bool isWritable = true)
{
return addData (name, mp, isWritable);
}
//--------------------------------------------------------------------------
/**
Add or replace a data member.
*/
template <class U>
Class <T>& addData (char const* name, U T::* mp, bool isWritable = true)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
typedef const U T::*mp_t;
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); // Stack: co, cl, st, field ptr
lua_pushcclosure (L, &CFunc::getProperty <T, U>, 1); // Stack: co, cl, st, getter
lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter
CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -3); // Stack: co, cl, st
if (isWritable)
{
new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); // Stack: co, cl, st, field ptr
lua_pushcclosure (L, &CFunc::setProperty <T, U>, 1); // Stack: co, cl, st, setter
CFunc::addSetter (L, name, -3); // Stack: co, cl, st
}
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a property member.
*/
template <class TG, class TS = TG>
Class <T>& addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS) = 0)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
typedef TG (T::*get_t) () const;
new (lua_newuserdata (L, sizeof (get_t))) get_t (get); // Stack: co, cl, st, funcion ptr
lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1); // Stack: co, cl, st, getter
lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter
CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -3); // Stack: co, cl, st
if (set != 0)
{
typedef void (T::* set_t) (TS);
new (lua_newuserdata (L, sizeof (set_t))) set_t (set); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1); // Stack: co, cl, st, setter
CFunc::addSetter (L, name, -3); // Stack: co, cl, st
}
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a property member.
*/
template <class TG, class TS = TG>
Class <T>& addProperty (char const* name, TG (T::* get) (lua_State*) const, void (T::* set) (TS, lua_State*) = 0)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
typedef TG (T::*get_t) (lua_State*) const;
new (lua_newuserdata (L, sizeof (get_t))) get_t (get); // Stack: co, cl, st, funcion ptr
lua_pushcclosure (L, &CFunc::CallConstMember <get_t>::f, 1); // Stack: co, cl, st, getter
lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter
CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -3); // Stack: co, cl, st
if (set != 0)
{
typedef void (T::* set_t) (TS, lua_State*);
new (lua_newuserdata (L, sizeof (set_t))) set_t (set); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::CallMember <set_t>::f, 1); // Stack: co, cl, st, setter
CFunc::addSetter (L, name, -3); // Stack: co, cl, st
}
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a property member, by proxy.
When a class is closed for modification and does not provide (or cannot
provide) the function signatures necessary to implement get or set for
a property, this will allow non-member functions act as proxies.
Both the get and the set functions require a T const* and T* in the first
argument respectively.
*/
template <class TG, class TS = TG>
Class <T>& addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS) = 0)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushlightuserdata (L, reinterpret_cast <void*> (get)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::Call <TG (*) (const T*)>::f, 1); // Stack: co, cl, st, getter
lua_pushvalue (L, -1); // Stack: co, cl, st,, getter, getter
CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -3); // Stack: co, cl, st
if (set != 0)
{
lua_pushlightuserdata (L, reinterpret_cast <void*> (set)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::Call <void (*) (T*, TS)>::f, 1); // Stack: co, cl, st, setter
CFunc::addSetter (L, name, -3); // Stack: co, cl, st
}
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a property member, by proxy C-function.
When a class is closed for modification and does not provide (or cannot
provide) the function signatures necessary to implement get or set for
a property, this will allow non-member functions act as proxies.
The object userdata ('this') value is at the index 1.
The new value for set function is at the index 2.
*/
Class <T>& addProperty (char const* name, int (*get) (lua_State*), int (*set) (lua_State*) = 0)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushcfunction (L, get);
lua_pushvalue (L, -1); // Stack: co, cl, st,, getter, getter
CFunc::addGetter (L, name, -5); // Stack: co, cl, st,, getter
CFunc::addGetter (L, name, -3); // Stack: co, cl, st,
if (set != 0)
{
lua_pushcfunction (L, set);
CFunc::addSetter (L, name, -3); // Stack: co, cl, st,
}
return *this;
}
#ifdef LUABRIDGE_CXX11
template <class TG, class TS = TG>
Class <T>& addProperty (char const* name,
std::function <TG (const T*)> get,
std::function <void (T*, TS)> set = nullptr)
{
using GetType = decltype (get);
new (lua_newuserdata (L, sizeof (get))) GetType (std::move (get)); // Stack: co, cl, st, function userdata (ud)
lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt)
lua_pushcfunction (L, &CFunc::gcMetaMethodAny <GetType>); // Stack: co, cl, st, ud, mt, gc function
rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt
lua_setmetatable (L, -2); // Stack: co, cl, st, ud
lua_pushcclosure (L, &CFunc::CallProxyFunctor <GetType>::f, 1); // Stack: co, cl, st, getter
lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter
CFunc::addGetter (L, name, -4); // Stack: co, cl, st, getter
CFunc::addGetter (L, name, -4); // Stack: co, cl, st
if (set != nullptr)
{
using SetType = decltype (set);
new (lua_newuserdata (L, sizeof (set))) SetType (std::move (set)); // Stack: co, cl, st, function userdata (ud)
lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt)
lua_pushcfunction (L, &CFunc::gcMetaMethodAny <SetType>); // Stack: co, cl, st, ud, mt, gc function
rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt
lua_setmetatable (L, -2); // Stack: co, cl, st, ud
lua_pushcclosure (L, &CFunc::CallProxyFunctor <SetType>::f, 1); // Stack: co, cl, st, setter
CFunc::addSetter (L, name, -3); // Stack: co, cl, st
}
return *this;
}
#endif // LUABRIDGE_CXX11
#ifndef LUABRIDGE_CXX11
//--------------------------------------------------------------------------
/**
Add or replace a member function.
*/
template <class MemFn>
Class <T>& addFunction (char const* name, MemFn mf)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
static const std::string GC = "__gc";
if (name == GC)
{
throw std::logic_error (GC + " metamethod registration is forbidden");
}
CFunc::CallMemberFunctionHelper <MemFn, FuncTraits <MemFn>::isConstMemberFunction>::add (L, name, mf);
return *this;
}
#else // ifndef LUABRIDGE_CXX11
//--------------------------------------------------------------------------
/**
Add or replace a member function by std::function.
*/
template <class ReturnType, class... Params>
Class <T>& addFunction (char const* name, std::function <ReturnType (T*, Params...)> function)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
using FnType = decltype (function);
new (lua_newuserdata (L, sizeof (function))) FnType (std::move (function)); // Stack: co, cl, st, function userdata (ud)
lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt)
lua_pushcfunction (L, &CFunc::gcMetaMethodAny <FnType>); // Stack: co, cl, st, ud, mt, gc function
rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt
lua_setmetatable (L, -2); // Stack: co, cl, st, ud
lua_pushcclosure (L, &CFunc::CallProxyFunctor <FnType>::f, 1); // Stack: co, cl, st, function
rawsetfield (L, -3, name); // Stack: co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a const member function by std::function.
*/
template <class ReturnType, class... Params>
Class <T>& addFunction (char const* name, std::function <ReturnType (const T*, Params...)> function)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
using FnType = decltype (function);
new (lua_newuserdata (L, sizeof (function))) FnType (std::move (function)); // Stack: co, cl, st, function userdata (ud)
lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt)
lua_pushcfunction (L, &CFunc::gcMetaMethodAny <FnType>); // Stack: co, cl, st, ud, mt, gc function
rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt
lua_setmetatable (L, -2); // Stack: co, cl, st, ud
lua_pushcclosure (L, &CFunc::CallProxyFunctor <FnType>::f, 1); // Stack: co, cl, st, function
lua_pushvalue (L, -1); // Stack: co, cl, st, function, function
rawsetfield (L, -4, name); // Stack: co, cl, st, function
rawsetfield (L, -4, name); // Stack: co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a member function.
*/
template <class ReturnType, class... Params>
Class <T>& addFunction (char const* name, ReturnType (T::* mf) (Params...))
{
using MemFn = ReturnType (T::*) (Params...);
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
static const std::string GC = "__gc";
if (name == GC)
{
throw std::logic_error (GC + " metamethod registration is forbidden");
}
CFunc::CallMemberFunctionHelper <MemFn, false>::add (L, name, mf);
return *this;
}
template <class ReturnType, class... Params>
Class <T>& addFunction (char const* name, ReturnType (T::* mf) (Params...) const)
{
using MemFn = ReturnType (T::*) (Params...) const;
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
static const std::string GC = "__gc";
if (name == GC)
{
throw std::logic_error (GC + " metamethod registration is forbidden");
}
CFunc::CallMemberFunctionHelper <MemFn, true>::add (L, name, mf);
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a proxy function.
*/
template <class ReturnType, class... Params>
Class <T>& addFunction (char const* name, ReturnType (*proxyFn) (T* object, Params...))
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
static const std::string GC = "__gc";
if (name == GC)
{
throw std::logic_error (GC + " metamethod registration is forbidden");
}
using FnType = decltype (proxyFn);
lua_pushlightuserdata (L, reinterpret_cast <void*> (proxyFn)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::CallProxyFunction <FnType>::f, 1); // Stack: co, cl, st, function
rawsetfield (L, -3, name); // Stack: co, cl, st
return *this;
}
template <class ReturnType, class... Params>
Class <T>& addFunction (char const* name, ReturnType (*proxyFn) (const T* object, Params...))
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
static const std::string GC = "__gc";
if (name == GC)
{
throw std::logic_error (GC + " metamethod registration is forbidden");
}
using FnType = decltype (proxyFn);
lua_pushlightuserdata (L, reinterpret_cast <void*> (proxyFn)); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::CallProxyFunction <FnType>::f, 1); // Stack: co, cl, st, function
lua_pushvalue (L, -1); // Stack: co, cl, st, function, function
rawsetfield (L, -4, name); // Stack: co, cl, st, function
rawsetfield (L, -4, name); // Stack: co, cl, st
return *this;
}
#endif
//--------------------------------------------------------------------------
/**
Add or replace a member lua_CFunction.
*/
Class <T>& addFunction (char const* name, int (T::*mfp) (lua_State*))
{
return addCFunction (name, mfp);
}
//--------------------------------------------------------------------------
/**
Add or replace a member lua_CFunction.
*/
Class <T>& addCFunction (char const* name, int (T::*mfp) (lua_State*))
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
typedef int (T::*MFP) (lua_State*);
new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); // Stack: co, cl, st, function ptr
lua_pushcclosure (L, &CFunc::CallMemberCFunction <T>::f, 1); // Stack: co, cl, st, function
rawsetfield (L, -3, name); // Stack: co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a const member lua_CFunction.
*/
Class <T>& addFunction (char const* name, int (T::*mfp) (lua_State*) const)
{
return addCFunction (name, mfp);
}
//--------------------------------------------------------------------------
/**
Add or replace a const member lua_CFunction.
*/
Class <T>& addCFunction (char const* name, int (T::*mfp) (lua_State*) const)
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
typedef int (T::*MFP) (lua_State*) const;
new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp);
lua_pushcclosure (L, &CFunc::CallConstMemberCFunction <T>::f, 1);
lua_pushvalue (L, -1); // Stack: co, cl, st, function, function
rawsetfield (L, -4, name); // Stack: co, cl, st, function
rawsetfield (L, -4, name); // Stack: co, cl, st
return *this;
}
//--------------------------------------------------------------------------
/**
Add or replace a primary Constructor.
The primary Constructor is invoked when calling the class type table
like a function.
The template parameter should be a function pointer type that matches
the desired Constructor (since you can't take the address of a Constructor
and pass it as an argument).
*/
template <class MemFn, class C>
Class <T>& addConstructor ()
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushcclosure (L, &ctorContainerProxy <typename FuncTraits <MemFn>::Params, C>, 0);
rawsetfield (L, -2, "__call");
return *this;
}
template <class MemFn>
Class <T>& addConstructor ()
{
assertStackState (); // Stack: const table (co), class table (cl), static table (st)
lua_pushcclosure (L, &ctorPlacementProxy <typename FuncTraits <MemFn>::Params, T>, 0);
rawsetfield (L, -2, "__call");
return *this;
}
};
private:
//----------------------------------------------------------------------------
/**
Open the global namespace for registrations.
*/
explicit Namespace (lua_State* L)
: Registrar (L)
{
lua_getglobal (L, "_G");
++m_stackSize;
}
//----------------------------------------------------------------------------
/**
Open a namespace for registrations.
The namespace is created if it doesn't already exist.
The parent namespace is at the top of the Lua stack.
*/
Namespace (char const* name, Namespace& parent)
: Registrar (parent)
{
assert (lua_istable (L, -1)); // Stack: parent namespace (pns)
rawgetfield (L, -1, name); // Stack: pns, namespace (ns) | nil
if (lua_isnil (L, -1)) // Stack: pns, nil
{
lua_pop (L, 1); // Stack: pns
lua_newtable (L); // Stack: pns, ns
lua_pushvalue (L, -1); // Stack: pns, ns, ns
// na.__metatable = ns
lua_setmetatable (L, -2); // Stack: pns, ns
// ns.__index = indexMetaMethod
lua_pushcfunction (L, &CFunc::indexMetaMethod);
rawsetfield (L, -2, "__index"); // Stack: pns, ns
// ns.__newindex = newindexMetaMethod
lua_pushcfunction (L, &CFunc::newindexStaticMetaMethod);
rawsetfield (L, -2, "__newindex"); // Stack: pns, ns
lua_newtable (L); // Stack: pns, ns, propget table (pg)
lua_rawsetp (L, -2, getPropgetKey ()); // ns [propgetKey] = pg. Stack: pns, ns
lua_newtable (L); // Stack: pns, ns, propset table (ps)
lua_rawsetp (L, -2, getPropsetKey ()); // ns [propsetKey] = ps. Stack: pns, ns
// pns [name] = ns
lua_pushvalue (L, -1); // Stack: pns, ns, ns
rawsetfield (L, -3, name); // Stack: pns, ns
#if 0
lua_pushcfunction (L, &tostringMetaMethod);
rawsetfield (L, -2, "__tostring");
#endif
}
++m_stackSize;
}
//----------------------------------------------------------------------------
/**
Close the class and continue the namespace registrations.
*/
explicit Namespace (ClassBase& child)
: Registrar (child)
{
}
using Registrar::operator=;
public:
//----------------------------------------------------------------------------
/**
Open the global namespace.
*/
static Namespace getGlobalNamespace (lua_State* L)
{
enableExceptions (L);
return Namespace (L);
}
//----------------------------------------------------------------------------
/**
Open a new or existing namespace for registrations.
*/
Namespace beginNamespace (char const* name)
{
assertIsActive ();
return Namespace (name, *this);
}
//----------------------------------------------------------------------------
/**
Continue namespace registration in the parent.
Do not use this on the global namespace.
*/
Namespace endNamespace ()
{
if (m_stackSize == 1)
{
throw std::logic_error ("endNamespace () called on global namespace");
}
assert (m_stackSize > 1);
--m_stackSize;
lua_pop (L, 1);
return Namespace (*this);
}
//----------------------------------------------------------------------------
/**
Add or replace a variable.
*/
template <class T>
Namespace& addProperty (char const* name, T* pt, bool isWritable = true)
{
return addVariable (name, pt, isWritable);
}
//----------------------------------------------------------------------------
/**
Add or replace a variable.
*/
template <class T>
Namespace& addVariable (char const* name, T* pt, bool isWritable = true)
{
if (m_stackSize == 1)
{
throw std::logic_error ("addProperty () called on global namespace");
}
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
lua_pushlightuserdata (L, pt); // Stack: ns, pointer
lua_pushcclosure (L, &CFunc::getVariable <T>, 1); // Stack: ns, getter
CFunc::addGetter (L, name, -2); // Stack: ns
if (isWritable)
{
lua_pushlightuserdata (L, pt); // Stack: ns, pointer
lua_pushcclosure (L, &CFunc::setVariable <T>, 1); // Stack: ns, setter
}
else
{
lua_pushstring (L, name); // Stack: ns, ps, name
lua_pushcclosure (L, &CFunc::readOnlyError, 1); // Stack: ns, error_fn
}
CFunc::addSetter (L, name, -2); // Stack: ns
return *this;
}
//----------------------------------------------------------------------------
/**
Add or replace a property.
If the set function is omitted or null, the property is read-only.
*/
template <class TG, class TS = TG>
Namespace& addProperty (char const* name, TG (*get) (), void (*set) (TS) = 0)
{
if (m_stackSize == 1)
{
throw std::logic_error ("addProperty () called on global namespace");
}
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
lua_pushlightuserdata (L, reinterpret_cast <void*> (get)); // Stack: ns, function ptr
lua_pushcclosure (L, &CFunc::Call <TG (*) ()>::f, 1); // Stack: ns, getter
CFunc::addGetter (L, name, -2);
if (set != 0)
{
lua_pushlightuserdata(L, reinterpret_cast <void*> (set)); // Stack: ns, function ptr
lua_pushcclosure (L, &CFunc::Call <void (*) (TS)>::f, 1);
}
else
{
lua_pushstring (L, name);
lua_pushcclosure (L, &CFunc::readOnlyError, 1);
}
CFunc::addSetter (L, name, -2);
return *this;
}
//----------------------------------------------------------------------------
/**
Add or replace a property.
If the set function is omitted or null, the property is read-only.
*/
Namespace& addProperty (char const* name, int (*get) (lua_State*), int (*set) (lua_State*) = 0)
{
if (m_stackSize == 1)
{
throw std::logic_error ("addProperty () called on global namespace");
}
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
lua_pushcfunction (L, get); // Stack: ns, getter
CFunc::addGetter (L, name, -2); // Stack: ns
if (set != 0)
{
lua_pushcfunction(L, set); // Stack: ns, setter
CFunc::addSetter(L, name, -2); // Stack: ns
}
else
{
lua_pushstring(L, name); // Stack: ns, name
lua_pushcclosure(L, &CFunc::readOnlyError, 1); // Stack: ns, name, readOnlyError
CFunc::addSetter(L, name, -2); // Stack: ns
}
return *this;
}
//----------------------------------------------------------------------------
/**
Add or replace a free function.
*/
template <class FP>
Namespace& addFunction (char const* name, FP const fp)
{
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
lua_pushlightuserdata (L, reinterpret_cast <void*> (fp)); // Stack: ns, function ptr
lua_pushcclosure (L, &CFunc::Call <FP>::f, 1); // Stack: ns, function
rawsetfield (L, -2, name); // Stack: ns
return *this;
}
//----------------------------------------------------------------------------
/**
Add or replace a lua_CFunction.
*/
Namespace& addFunction (char const* name, int (*const fp) (lua_State*))
{
return addCFunction (name, fp);
}
//----------------------------------------------------------------------------
/**
Add or replace a lua_CFunction.
*/
Namespace& addCFunction (char const* name, int (*const fp) (lua_State*))
{
assert (lua_istable (L, -1)); // Stack: namespace table (ns)
lua_pushcfunction (L, fp); // Stack: ns, function
rawsetfield (L, -2, name); // Stack: ns
return *this;
}
//----------------------------------------------------------------------------
/**
Open a new or existing class for registrations.
*/
template <class T>
Class <T> beginClass (char const* name)
{
assertIsActive ();
return Class <T> (name, *this);
}
//----------------------------------------------------------------------------
/**
Derive a new class for registrations.
To continue registrations for the class later, use beginClass ().
Do not call deriveClass () again.
*/
template <class Derived, class Base>
Class <Derived> deriveClass (char const* name)
{
assertIsActive ();
return Class <Derived> (name, *this, ClassInfo <Base>::getStaticKey ());
}
};
//------------------------------------------------------------------------------
/**
Retrieve the global namespace.
It is recommended to put your namespace inside the global namespace, and
then add your classes and functions to it, rather than adding many classes
and functions directly to the global namespace.
*/
inline Namespace getGlobalNamespace (lua_State* L)
{
return Namespace::getGlobalNamespace (L);
}
} // namespace luabridge

View File

@@ -0,0 +1,62 @@
#pragma once
namespace luabridge {
//------------------------------------------------------------------------------
/**
security options.
*/
class Security
{
public:
static bool hideMetatables()
{
return getSettings().hideMetatables;
}
static void setHideMetatables(bool shouldHide)
{
getSettings().hideMetatables = shouldHide;
}
private:
struct Settings
{
Settings() : hideMetatables(true)
{
}
bool hideMetatables;
};
static Settings& getSettings()
{
static Settings settings;
return settings;
}
};
//------------------------------------------------------------------------------
/**
Set a global value in the lua_State.
@note This works on any type specialized by `Stack`, including `LuaRef` and
its table proxies.
*/
template <class T>
inline void setGlobal(lua_State* L, T t, char const* name)
{
push(L, t);
lua_setglobal(L, name);
}
//------------------------------------------------------------------------------
/**
Change whether or not metatables are hidden (on by default).
*/
inline void setHideMetatables(bool shouldHide)
{
Security::setHideMetatables(shouldHide);
}
} // namespace luabridge

View File

@@ -0,0 +1,622 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/LuaHelpers.h>
#include <LuaBridge/detail/Userdata.h>
#include <string>
namespace luabridge {
template <class T>
struct Stack;
template <>
struct Stack <void>
{
static void push (lua_State* L)
{
}
};
//------------------------------------------------------------------------------
/**
Receive the lua_State* as an argument.
*/
template <>
struct Stack <lua_State*>
{
static lua_State* get (lua_State* L, int)
{
return L;
}
};
//------------------------------------------------------------------------------
/**
Push a lua_CFunction.
*/
template <>
struct Stack <lua_CFunction>
{
static void push (lua_State* L, lua_CFunction f)
{
lua_pushcfunction (L, f);
}
static lua_CFunction get (lua_State* L, int index)
{
return lua_tocfunction (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return lua_iscfunction (L, index);
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `int`.
*/
template <>
struct Stack <int>
{
static void push (lua_State* L, int value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static int get (lua_State* L, int index)
{
return static_cast <int> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `unsigned int`.
*/
template <>
struct Stack <unsigned int>
{
static void push (lua_State* L, unsigned int value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static unsigned int get (lua_State* L, int index)
{
return static_cast <unsigned int> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `unsigned char`.
*/
template <>
struct Stack <unsigned char>
{
static void push (lua_State* L, unsigned char value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static unsigned char get (lua_State* L, int index)
{
return static_cast <unsigned char> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `short`.
*/
template <>
struct Stack <short>
{
static void push (lua_State* L, short value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static short get (lua_State* L, int index)
{
return static_cast <short> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `unsigned short`.
*/
template <>
struct Stack <unsigned short>
{
static void push (lua_State* L, unsigned short value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static unsigned short get (lua_State* L, int index)
{
return static_cast <unsigned short> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `long`.
*/
template <>
struct Stack <long>
{
static void push (lua_State* L, long value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static long get (lua_State* L, int index)
{
return static_cast <long> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `unsigned long`.
*/
template <>
struct Stack <unsigned long>
{
static void push (lua_State* L, unsigned long value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static unsigned long get (lua_State* L, int index)
{
return static_cast <unsigned long> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
* Stack specialization for `long long`.
*/
template <>
struct Stack <long long>
{
static void push (lua_State* L, long long value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static long long get (lua_State* L, int index)
{
return static_cast <long long> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
* Stack specialization for `unsigned long long`.
*/
template <>
struct Stack <unsigned long long>
{
static void push (lua_State* L, unsigned long long value)
{
lua_pushinteger (L, static_cast <lua_Integer> (value));
}
static unsigned long long get (lua_State* L, int index)
{
return static_cast <unsigned long long> (luaL_checkinteger (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `float`.
*/
template <>
struct Stack <float>
{
static void push (lua_State* L, float value)
{
lua_pushnumber (L, static_cast <lua_Number> (value));
}
static float get (lua_State* L, int index)
{
return static_cast <float> (luaL_checknumber (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `double`.
*/
template <>
struct Stack <double>
{
static void push (lua_State* L, double value)
{
lua_pushnumber (L, static_cast <lua_Number> (value));
}
static double get (lua_State* L, int index)
{
return static_cast <double> (luaL_checknumber (L, index));
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TNUMBER;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `bool`.
*/
template <>
struct Stack <bool>
{
static void push (lua_State* L, bool value)
{
lua_pushboolean (L, value ? 1 : 0);
}
static bool get (lua_State* L, int index)
{
return lua_toboolean (L, index) ? true : false;
}
static bool isInstance (lua_State* L, int index)
{
return lua_isboolean (L, index);
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `char`.
*/
template <>
struct Stack <char>
{
static void push (lua_State* L, char value)
{
lua_pushlstring (L, &value, 1);
}
static char get (lua_State* L, int index)
{
return luaL_checkstring (L, index) [0];
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TSTRING;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `const char*`.
*/
template <>
struct Stack <char const*>
{
static void push (lua_State* L, char const* str)
{
if (str != 0)
lua_pushstring (L, str);
else
lua_pushnil (L);
}
static char const* get (lua_State* L, int index)
{
return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return lua_isnil (L, index) || lua_type (L, index) == LUA_TSTRING;
}
};
//------------------------------------------------------------------------------
/**
Stack specialization for `std::string`.
*/
template <>
struct Stack <std::string>
{
static void push (lua_State* L, std::string const& str)
{
lua_pushlstring (L, str.data (), str.size ());
}
static std::string get (lua_State* L, int index)
{
size_t len;
if (lua_type (L, index) == LUA_TSTRING)
{
const char* str = lua_tolstring (L, index, &len);
return std::string (str, len);
}
// Lua reference manual:
// If the value is a number, then lua_tolstring also changes the actual value in the stack to a string.
// (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.)
lua_pushvalue (L, index);
const char* str = lua_tolstring(L, -1, &len);
std::string string (str, len);
lua_pop (L, 1); // Pop the temporary string
return string;
}
static bool isInstance (lua_State* L, int index)
{
return lua_type (L, index) == LUA_TSTRING;
}
};
template <class T>
struct StackOpSelector <T&, false>
{
typedef T ReturnType;
static void push (lua_State* L, T& value)
{
Stack <T>::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Stack <T>::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Stack <T>::isInstance (L, index);
}
};
template <class T>
struct StackOpSelector <const T&, false>
{
typedef T ReturnType;
static void push (lua_State* L, const T& value)
{
Stack <T>::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Stack <T>::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Stack <T>::isInstance (L, index);
}
};
template <class T>
struct StackOpSelector <T*, false>
{
typedef T ReturnType;
static void push (lua_State* L, T* value)
{
Stack <T>::push (L, *value);
}
static ReturnType get (lua_State* L, int index)
{
return Stack <T>::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Stack <T>::isInstance (L, index);
}
};
template <class T>
struct StackOpSelector <const T*, false>
{
typedef T ReturnType;
static void push (lua_State* L, const T* value)
{
Stack <T>::push (L, *value);
}
static ReturnType get (lua_State* L, int index)
{
return Stack <T>::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Stack <T>::isInstance (L, index);
}
};
template <class T>
struct Stack <T&>
{
typedef StackOpSelector <T&, IsUserdata <T>::value> Helper;
typedef typename Helper::ReturnType ReturnType;
static void push (lua_State* L, T& value)
{
Helper::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Helper::get (L, index);
}
};
template <class T>
struct Stack <const T&>
{
typedef StackOpSelector <const T&, IsUserdata <T>::value> Helper;
typedef typename Helper::ReturnType ReturnType;
static void push (lua_State* L, const T& value)
{
Helper::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Helper::get (L, index);
}
};
template <class T>
struct Stack <T*>
{
typedef StackOpSelector <T*, IsUserdata <T>::value> Helper;
typedef typename Helper::ReturnType ReturnType;
static void push (lua_State* L, T* value)
{
Helper::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Helper::get (L, index);
}
};
template <class T>
struct Stack <const T*>
{
typedef StackOpSelector <const T*, IsUserdata <T>::value> Helper;
typedef typename Helper::ReturnType ReturnType;
static void push (lua_State* L, const T* value)
{
Helper::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Helper::get (L, index);
}
};
//------------------------------------------------------------------------------
/**
* Push an object onto the Lua stack.
*/
template <class T>
inline void push (lua_State* L, T t)
{
Stack <T>::push (L, t);
}
//------------------------------------------------------------------------------
/**
* Check whether an object on the Lua stack is of type T.
*/
template <class T>
inline bool isInstance (lua_State* L, int index)
{
return Stack <T>::isInstance (L, index);
}
} // namespace luabridge

View File

@@ -0,0 +1,218 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This file incorporates work covered by the following copyright and
permission notice:
The Loki Library
Copyright (c) 2001 by Andrei Alexandrescu
This code accompanies the book:
Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
Patterns Applied". Copyright (c) 2001. Addison-Wesley.
Permission to use, copy, modify, distribute and sell this software for any
purpose is hereby granted without fee, provided that the above copyright
notice appear in all copies and that both that copyright notice and this
permission notice appear in supporting documentation.
The author or Addison-Welsey Longman make no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/Config.h>
#include <LuaBridge/detail/Stack.h>
#include <string>
#include <typeinfo>
namespace luabridge {
/**
None type means void parameters or return value.
*/
typedef void None;
template <typename Head, typename Tail = None>
struct TypeList
{
typedef Tail TailType;
};
template <class List>
struct TypeListSize
{
static const size_t value = TypeListSize <typename List::TailType>::value + 1;
};
template <>
struct TypeListSize <None>
{
static const size_t value = 0;
};
#ifdef LUABRIDGE_CXX11
template <class... Params>
struct MakeTypeList;
template <class Param, class... Params>
struct MakeTypeList <Param, Params...>
{
using Result = TypeList <Param, typename MakeTypeList <Params...>::Result>;
};
template <>
struct MakeTypeList <>
{
using Result = None;
};
#endif
/**
A TypeList with actual values.
*/
template <typename List>
struct TypeListValues
{
static std::string const tostring (bool)
{
return "";
}
};
/**
TypeListValues recursive template definition.
*/
template <typename Head, typename Tail>
struct TypeListValues <TypeList <Head, Tail> >
{
Head hd;
TypeListValues <Tail> tl;
TypeListValues (Head hd_, TypeListValues <Tail> const& tl_)
: hd (hd_), tl (tl_)
{
}
static std::string tostring (bool comma = false)
{
std::string s;
if (comma)
s = ", ";
s = s + typeid (Head).name ();
return s + TypeListValues <Tail>::tostring (true);
}
};
// Specializations of type/value list for head types that are references and
// const-references. We need to handle these specially since we can't count
// on the referenced object hanging around for the lifetime of the list.
template <typename Head, typename Tail>
struct TypeListValues <TypeList <Head&, Tail> >
{
Head hd;
TypeListValues <Tail> tl;
TypeListValues (Head& hd_, TypeListValues <Tail> const& tl_)
: hd (hd_), tl (tl_)
{
}
static std::string const tostring (bool comma = false)
{
std::string s;
if (comma)
s = ", ";
s = s + typeid (Head).name () + "&";
return s + TypeListValues <Tail>::tostring (true);
}
};
template <typename Head, typename Tail>
struct TypeListValues <TypeList <Head const&, Tail> >
{
Head hd;
TypeListValues <Tail> tl;
TypeListValues (Head const& hd_, const TypeListValues <Tail>& tl_)
: hd (hd_), tl (tl_)
{
}
static std::string const tostring (bool comma = false)
{
std::string s;
if (comma)
s = ", ";
s = s + typeid (Head).name () + " const&";
return s + TypeListValues <Tail>::tostring (true);
}
};
//==============================================================================
/**
Subclass of a TypeListValues constructable from the Lua stack.
*/
template <typename List, int Start = 1>
struct ArgList
{
};
template <int Start>
struct ArgList <None, Start> : public TypeListValues <None>
{
ArgList (lua_State*)
{
}
};
template <typename Head, typename Tail, int Start>
struct ArgList <TypeList <Head, Tail>, Start>
: public TypeListValues <TypeList <Head, Tail> >
{
ArgList (lua_State* L)
: TypeListValues <TypeList <Head, Tail> > (Stack <Head>::get (L, Start),
ArgList <Tail, Start + 1> (L))
{
}
};
} // namespace luabridge

View File

@@ -0,0 +1,135 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <string>
namespace luabridge {
//------------------------------------------------------------------------------
/**
Container traits.
Unspecialized ContainerTraits has the isNotContainer typedef for SFINAE.
All user defined containers must supply an appropriate specialization for
ContinerTraits (without the typedef isNotContainer). The containers that
come with LuaBridge also come with the appropriate ContainerTraits
specialization. See the corresponding declaration for details.
A specialization of ContainerTraits for some generic type ContainerType
looks like this:
template <class T>
struct ContainerTraits <ContainerType <T> >
{
typedef typename T Type;
static T* get (ContainerType <T> const& c)
{
return c.get (); // Implementation-dependent on ContainerType
}
};
*/
template <class T>
struct ContainerTraits
{
typedef bool isNotContainer;
typedef T Type;
};
//------------------------------------------------------------------------------
/**
Type traits.
Specializations return information about a type.
*/
struct TypeTraits
{
/** Determine if type T is a container.
To be considered a container, there must be a specialization of
ContainerTraits with the required fields.
*/
template <typename T>
class isContainer
{
private:
typedef char yes[1]; // sizeof (yes) == 1
typedef char no [2]; // sizeof (no) == 2
template <typename C>
static no& test (typename C::isNotContainer*);
template <typename>
static yes& test (...);
public:
static const bool value = sizeof (test <ContainerTraits <T> >(0)) == sizeof (yes);
};
/** Determine if T is const qualified.
*/
/** @{ */
template <class T>
struct isConst
{
static bool const value = false;
};
template <class T>
struct isConst <T const>
{
static bool const value = true;
};
/** @} */
/** Remove the const qualifier from T.
*/
/** @{ */
template <class T>
struct removeConst
{
typedef T Type;
};
template <class T>
struct removeConst <T const>
{
typedef T Type;
};
/**@}*/
};
template <class T>
struct Stack;
} // namespace luabridge

View File

@@ -0,0 +1,829 @@
//------------------------------------------------------------------------------
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include <LuaBridge/detail/ClassInfo.h>
#include <cassert>
#include <stdexcept>
namespace luabridge {
//==============================================================================
/**
Return the identity pointer for our lightuserdata tokens.
Because of Lua's dynamic typing and our improvised system of imposing C++
class structure, there is the possibility that executing scripts may
knowingly or unknowingly cause invalid data to get passed to the C functions
created by LuaBridge. In particular, our security model addresses the
following:
1. Scripts cannot create a userdata (ignoring the debug lib).
2. Scripts cannot create a lightuserdata (ignoring the debug lib).
3. Scripts cannot set the metatable on a userdata.
*/
/**
Interface to a class pointer retrievable from a userdata.
*/
class Userdata
{
protected:
void* m_p; // subclasses must set this
Userdata() : m_p (0)
{
}
//--------------------------------------------------------------------------
/**
Get an untyped pointer to the contained class.
*/
void* getPointer ()
{
return m_p;
}
private:
//--------------------------------------------------------------------------
/**
Validate and retrieve a Userdata on the stack.
The Userdata must exactly match the corresponding class table or
const table, or else a Lua error is raised. This is used for the
__gc metamethod.
*/
static Userdata* getExactClass (lua_State* L, int index, void const* /*classKey*/)
{
return static_cast <Userdata*> (lua_touserdata (L, lua_absindex (L, index)));
}
//--------------------------------------------------------------------------
/**
Validate and retrieve a Userdata on the stack.
The Userdata must be derived from or the same as the given base class,
identified by the key. If canBeConst is false, generates an error if
the resulting Userdata represents to a const object. We do the type check
first so that the error message is informative.
*/
static Userdata* getClass (lua_State* L,
int index,
void const* registryConstKey,
void const* registryClassKey,
bool canBeConst)
{
index = lua_absindex (L, index);
lua_getmetatable (L, index); // Stack: object metatable (ot) | nil
if (!lua_istable (L, -1))
{
lua_rawgetp (L, LUA_REGISTRYINDEX, registryClassKey); // Stack: registry metatable (rt) | nil
return throwBadArg (L, index);
}
lua_rawgetp (L, -1, getConstKey ()); // Stack: ot | nil, const table (co) | nil
assert (lua_istable (L, -1) || lua_isnil (L, -1));
// If const table is NOT present, object is const. Use non-const registry table
// if object cannot be const, so constness validation is done automatically.
// E.g. nonConstFn (constObj)
// -> canBeConst = false, isConst = true
// -> 'Class' registry table, 'const Class' object table
// -> 'expected Class, got const Class'
bool isConst = lua_isnil (L, -1); // Stack: ot | nil, nil, rt
if (isConst && canBeConst)
{
lua_rawgetp (L, LUA_REGISTRYINDEX, registryConstKey); // Stack: ot, nil, rt
}
else
{
lua_rawgetp (L, LUA_REGISTRYINDEX, registryClassKey); // Stack: ot, co, rt
}
lua_insert (L, -3); // Stack: rt, ot, co | nil
lua_pop (L, 1); // Stack: rt, ot
for (;;)
{
if (lua_rawequal (L, -1, -2)) // Stack: rt, ot
{
lua_pop (L, 2); // Stack: -
return static_cast <Userdata*> (lua_touserdata (L, index));
}
// Replace current metatable with it's base class.
lua_rawgetp (L, -1, getParentKey ()); // Stack: rt, ot, parent ot (pot) | nil
if (lua_isnil (L, -1)) // Stack: rt, ot, nil
{
// Drop the object metatable because it may be some parent metatable
lua_pop (L, 2); // Stack: rt
return throwBadArg (L, index);
}
lua_remove (L, -2); // Stack: rt, pot
}
// no return
}
static bool isInstance (lua_State* L, int index, void const* registryClassKey)
{
index = lua_absindex (L, index);
int result = lua_getmetatable (L, index); // Stack: object metatable (ot) | nothing
if (result == 0)
{
return false; // Nothing was pushed on the stack
}
if (!lua_istable (L, -1))
{
lua_pop (L, 1); // Stack: -
return false;
}
lua_rawgetp (L, LUA_REGISTRYINDEX, registryClassKey); // Stack: ot, rt
lua_insert (L, -2); // Stack: rt, ot
for (;;)
{
if (lua_rawequal (L, -1, -2)) // Stack: rt, ot
{
lua_pop (L, 2); // Stack: -
return true;
}
// Replace current metatable with it's base class.
lua_rawgetp (L, -1, getParentKey ()); // Stack: rt, ot, parent ot (pot) | nil
if (lua_isnil (L, -1)) // Stack: rt, ot, nil
{
lua_pop (L, 3); // Stack: -
return false;
}
lua_remove (L, -2); // Stack: rt, pot
}
}
static Userdata* throwBadArg (lua_State* L, int index)
{
assert (lua_istable (L, -1) || lua_isnil (L, -1)); // Stack: rt | nil
const char* expected = 0;
if (lua_isnil (L, -1)) // Stack: nil
{
expected = "unregistered class";
}
else
{
lua_rawgetp (L, -1, getTypeKey ()); // Stack: rt, registry type
expected = lua_tostring (L, -1);
}
const char* got = 0;
if (lua_isuserdata (L, index))
{
lua_getmetatable (L, index); // Stack: ..., ot | nil
if (lua_istable (L, -1)) // Stack: ..., ot
{
lua_rawgetp (L, -1, getTypeKey ()); // Stack: ..., ot, object type | nil
if (lua_isstring (L, -1))
{
got = lua_tostring (L, -1);
}
}
}
if (!got)
{
got = lua_typename (L, lua_type (L, index));
}
luaL_argerror (L, index, lua_pushfstring (L, "%s expected, got %s", expected, got));
return 0;
}
public:
virtual ~Userdata () { }
//--------------------------------------------------------------------------
/**
Returns the Userdata* if the class on the Lua stack matches.
If the class does not match, a Lua error is raised.
*/
template <class T>
static Userdata* getExact (lua_State* L, int index)
{
return getExactClass (L, index, ClassInfo <T>::getClassKey ());
}
//--------------------------------------------------------------------------
/**
Get a pointer to the class from the Lua stack.
If the object is not the class or a subclass, or it violates the
const-ness, a Lua error is raised.
*/
template <class T>
static T* get (lua_State* L, int index, bool canBeConst)
{
if (lua_isnil (L, index))
return 0;
return static_cast <T*> (getClass (
L, index, ClassInfo <T>::getConstKey (),
ClassInfo <T>::getClassKey (),
canBeConst)->getPointer ());
}
template <class T>
static bool isInstance (lua_State* L, int index)
{
return isInstance (L, index, ClassInfo <T>::getClassKey ());
}
};
//----------------------------------------------------------------------------
/**
Wraps a class object stored in a Lua userdata.
The lifetime of the object is managed by Lua. The object is constructed
inside the userdata using placement new.
*/
template <class T>
class UserdataValue : public Userdata
{
private:
UserdataValue <T> (UserdataValue <T> const&);
UserdataValue <T> operator= (UserdataValue <T> const&);
char m_storage [sizeof (T)];
private:
/**
Used for placement construction.
*/
UserdataValue ()
{
m_p = 0;
}
~UserdataValue ()
{
if (getPointer () != 0)
{
getObject ()->~T ();
}
}
public:
/**
Push a T via placement new.
The caller is responsible for calling placement new using the
returned uninitialized storage.
*/
static UserdataValue <T>* place (lua_State* const L)
{
UserdataValue <T>* const ud = new (
lua_newuserdata (L, sizeof (UserdataValue <T>))) UserdataValue <T> ();
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
if (!lua_istable (L, -1))
{
throw std::logic_error ("The class is not registered in LuaBridge");
}
lua_setmetatable (L, -2);
return ud;
}
/**
Push T via copy construction from U.
*/
template <class U>
static inline void push (lua_State* const L, U const& u)
{
UserdataValue <T>* ud = place (L);
new (ud->getObject ()) U (u);
ud->commit ();
}
/**
Confirm object construction.
*/
void commit ()
{
m_p = getObject ();
}
T* getObject ()
{
// If this fails to compile it means you forgot to provide
// a Container specialization for your container!
//
return reinterpret_cast <T*> (&m_storage [0]);
}
};
//----------------------------------------------------------------------------
/**
Wraps a pointer to a class object inside a Lua userdata.
The lifetime of the object is managed by C++.
*/
class UserdataPtr : public Userdata
{
private:
UserdataPtr (UserdataPtr const&);
UserdataPtr operator= (UserdataPtr const&);
private:
/** Push a pointer to object using metatable key.
*/
static void push (lua_State* L, const void* p, void const* const key)
{
new (lua_newuserdata (L, sizeof (UserdataPtr))) UserdataPtr (const_cast <void*> (p));
lua_rawgetp (L, LUA_REGISTRYINDEX, key);
if (!lua_istable (L, -1))
{
throw std::logic_error ("The class is not registered in LuaBridge");
}
lua_setmetatable (L, -2);
}
explicit UserdataPtr (void* const p)
{
m_p = p;
// Can't construct with a null pointer!
//
assert (m_p != 0);
}
public:
/** Push non-const pointer to object.
*/
template <class T>
static void push (lua_State* const L, T* const p)
{
if (p)
push (L, p, ClassInfo <T>::getClassKey ());
else
lua_pushnil (L);
}
/** Push const pointer to object.
*/
template <class T>
static void push (lua_State* const L, T const* const p)
{
if (p)
push (L, p, ClassInfo <T>::getConstKey ());
else
lua_pushnil (L);
}
};
//============================================================================
/**
Wraps a container that references a class object.
The template argument C is the container type, ContainerTraits must be
specialized on C or else a compile error will result.
*/
template <class C>
class UserdataShared : public Userdata
{
private:
UserdataShared (UserdataShared <C> const&);
UserdataShared <C>& operator= (UserdataShared <C> const&);
typedef typename TypeTraits::removeConst <
typename ContainerTraits <C>::Type>::Type T;
C m_c;
private:
~UserdataShared ()
{
}
public:
/**
Construct from a container to the class or a derived class.
*/
template <class U>
explicit UserdataShared (U const& u) : m_c (u)
{
m_p = const_cast <void*> (reinterpret_cast <void const*> (
(ContainerTraits <C>::get (m_c))));
}
/**
Construct from a pointer to the class or a derived class.
*/
template <class U>
explicit UserdataShared (U* u) : m_c (u)
{
m_p = const_cast <void*> (reinterpret_cast <void const*> (
(ContainerTraits <C>::get (m_c))));
}
};
//----------------------------------------------------------------------------
//
// SFINAE helpers.
//
// non-const objects
template <class C, bool makeObjectConst>
struct UserdataSharedHelper
{
typedef typename TypeTraits::removeConst <
typename ContainerTraits <C>::Type>::Type T;
static void push (lua_State* L, C const& c)
{
if (ContainerTraits <C>::get (c) != 0)
{
new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c);
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
// If this goes off it means the class T is unregistered!
assert (lua_istable (L, -1));
lua_setmetatable (L, -2);
}
else
{
lua_pushnil (L);
}
}
static void push (lua_State* L, T* const t)
{
if (t)
{
new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t);
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getClassKey ());
// If this goes off it means the class T is unregistered!
assert (lua_istable (L, -1));
lua_setmetatable (L, -2);
}
else
{
lua_pushnil (L);
}
}
};
// const objects
template <class C>
struct UserdataSharedHelper <C, true>
{
typedef typename TypeTraits::removeConst <
typename ContainerTraits <C>::Type>::Type T;
static void push (lua_State* L, C const& c)
{
if (ContainerTraits <C>::get (c) != 0)
{
new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (c);
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
// If this goes off it means the class T is unregistered!
assert (lua_istable (L, -1));
lua_setmetatable (L, -2);
}
else
{
lua_pushnil (L);
}
}
static void push (lua_State* L, T* const t)
{
if (t)
{
new (lua_newuserdata (L, sizeof (UserdataShared <C>))) UserdataShared <C> (t);
lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo <T>::getConstKey ());
// If this goes off it means the class T is unregistered!
assert (lua_istable (L, -1));
lua_setmetatable (L, -2);
}
else
{
lua_pushnil (L);
}
}
};
/**
Pass by container.
The container controls the object lifetime. Typically this will be a
lifetime shared by C++ and Lua using a reference count. Because of type
erasure, containers like std::shared_ptr will not work. Containers must
either be of the intrusive variety, or in the style of the RefCountedPtr
type provided by LuaBridge (that uses a global hash table).
*/
template <class C, bool byContainer>
struct StackHelper
{
static void push (lua_State* L, C const& c)
{
UserdataSharedHelper <C,
TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, c);
}
typedef typename TypeTraits::removeConst <
typename ContainerTraits <C>::Type>::Type T;
static C get (lua_State* L, int index)
{
return Userdata::get <T> (L, index, true);
}
};
/**
Pass by value.
Lifetime is managed by Lua. A C++ function which accesses a pointer or
reference to an object outside the activation record in which it was
retrieved may result in undefined behavior if Lua garbage collected it.
*/
template <class T>
struct StackHelper <T, false>
{
static inline void push (lua_State* L, T const& t)
{
UserdataValue <T>::push (L, t);
}
static inline T const& get (lua_State* L, int index)
{
return *Userdata::get <T> (L, index, true);
}
};
//------------------------------------------------------------------------------
/**
Lua stack conversions for pointers and references to class objects.
Lifetime is managed by C++. Lua code which remembers a reference to the
value may result in undefined behavior if C++ destroys the object. The
handling of the const and volatile qualifiers happens in UserdataPtr.
*/
template <class C, bool byContainer>
struct RefStackHelper
{
typedef C return_type;
static inline void push (lua_State* L, C const& t)
{
UserdataSharedHelper <C,
TypeTraits::isConst <typename ContainerTraits <C>::Type>::value>::push (L, t);
}
typedef typename TypeTraits::removeConst <
typename ContainerTraits <C>::Type>::Type T;
static return_type get (lua_State* L, int index)
{
return Userdata::get <T> (L, index, true);
}
};
template <class T>
struct RefStackHelper <T, false>
{
typedef T& return_type;
static void push (lua_State* L, T const& t)
{
UserdataPtr::push (L, &t);
}
static return_type get (lua_State* L, int index)
{
T* t = Userdata::get <T> (L, index, true);
if (!t)
luaL_error (L, "nil passed to reference");
return *t;
}
};
/**
* Voider class template. Used to force a comiler to instantiate
* an otherwise probably unused template parameter type T.
* See the C++20 std::void_t <> for details.
*/
template <class T>
struct Void
{
typedef void Type;
};
/**
* Trait class that selects whether to return a user registered
* class object by value or by reference.
*/
template <class T, class Enabler = void>
struct UserdataGetter
{
typedef T* ReturnType;
static ReturnType get (lua_State* L, int index)
{
return Userdata::get <T> (L, index, false);
}
};
template <class T>
struct UserdataGetter <T, typename Void <T (*) ()>::Type>
{
typedef T ReturnType;
static ReturnType get (lua_State* L, int index)
{
return StackHelper <T, TypeTraits::isContainer <T>::value>::get (L, index);
}
};
//==============================================================================
/**
Lua stack conversions for class objects passed by value.
*/
template <class T>
struct Stack
{
typedef void IsUserdata;
typedef UserdataGetter <T> Getter;
typedef typename Getter::ReturnType ReturnType;
static void push (lua_State* L, T const& value)
{
StackHelper <T, TypeTraits::isContainer <T>::value>::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Getter::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Userdata::isInstance <T> (L, index);
}
};
/**
* Trait class indicating whether the parameter type must be
* a user registered class. The trait checks the existence of
* member type Stack <T>::IsUserdata specialization for detection.
*/
template <class T, class Enable = void>
struct IsUserdata
{
static const bool value = false;
};
template <class T>
struct IsUserdata <T, typename Void <typename Stack <T>::IsUserdata>::Type>
{
static const bool value = true;
};
/**
* Trait class that selects a specific push/get implemenation.
*/
template <class T, bool isUserdata>
struct StackOpSelector;
// pointer
template <class T>
struct StackOpSelector <T*, true>
{
typedef T* ReturnType;
static void push (lua_State* L, T* value)
{
UserdataPtr::push (L, value);
}
static T* get (lua_State* L, int index)
{
return Userdata::get <T> (L, index, false);
}
static bool isInstance (lua_State* L, int index)
{
return Userdata::isInstance <T> (L, index);
}
};
// pointer to const
template <class T>
struct StackOpSelector <const T*, true>
{
typedef const T* ReturnType;
static void push (lua_State* L, const T* value)
{
UserdataPtr::push (L, value);
}
static const T* get (lua_State* L, int index)
{
return Userdata::get <T> (L, index, true);
}
static bool isInstance (lua_State* L, int index)
{
return Userdata::isInstance <T> (L, index);
}
};
// reference
template <class T>
struct StackOpSelector <T&, true>
{
typedef RefStackHelper <T, TypeTraits::isContainer <T>::value> Helper;
typedef typename Helper::return_type ReturnType;
static void push (lua_State* L, T& value)
{
UserdataPtr::push (L, &value);
}
static ReturnType get (lua_State* L, int index)
{
return Helper::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Userdata::isInstance <T> (L, index);
}
};
// reference to const
template <class T>
struct StackOpSelector <const T&, true>
{
typedef RefStackHelper <T, TypeTraits::isContainer <T>::value> Helper;
typedef typename Helper::return_type ReturnType;
static void push (lua_State* L, const T& value)
{
Helper::push (L, value);
}
static ReturnType get (lua_State* L, int index)
{
return Helper::get (L, index);
}
static bool isInstance (lua_State* L, int index)
{
return Userdata::isInstance <T> (L, index);
}
};
} // namespace luabridge

View File

@@ -0,0 +1,143 @@
//==============================================================================
/*
https://github.com/vinniefalco/LuaBridge
Copyright 2019, Dmitry Tarakanov
Copyright 2012, Vinnie Falco <vinnie.falco@gmail.com>
Copyright 2007, Nathan Reed
License: The MIT License (http://www.opensource.org/licenses/mit-license.php)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
//==============================================================================
#pragma once
#include "LuaBridge/detail/ClassInfo.h"
#include <iostream>
#include <string>
namespace luabridge {
namespace debug {
inline void putIndent (std::ostream& stream, unsigned level)
{
for (unsigned i = 0; i < level; ++i)
{
stream << " ";
}
}
inline void dumpTable (lua_State* L, int index, std::ostream& stream, unsigned level);
inline void dumpValue (lua_State* L, int index, std::ostream& stream, unsigned level = 0)
{
const int type = lua_type (L, index);
switch (type)
{
case LUA_TNIL:
stream << "nil";
break;
case LUA_TBOOLEAN:
stream << (lua_toboolean (L, index) ? "true" : "false");
break;
case LUA_TNUMBER:
stream << lua_tonumber (L, index);
break;
case LUA_TSTRING:
stream << '"' << lua_tostring (L, index) << '"';
break;
case LUA_TFUNCTION:
if (lua_iscfunction (L, index))
{
stream << "cfunction@" << lua_topointer (L, index);
}
else
{
stream << "function@" << lua_topointer (L, index);
}
break;
case LUA_TTHREAD:
stream << "thread@" << lua_tothread (L, index);
break;
case LUA_TLIGHTUSERDATA:
stream << "lightuserdata@" << lua_touserdata (L, index);
break;
case LUA_TTABLE:
dumpTable (L, index, stream, level);
break;
case LUA_TUSERDATA:
stream << "userdata@" << lua_touserdata (L, index);
break;
default:
stream << lua_typename (L, type);;
break;
}
}
inline void dumpTable (lua_State* L, int index, std::ostream& stream, unsigned level)
{
stream << "table@" << lua_topointer (L, index);
if (level > 0)
{
return;
}
index = lua_absindex (L, index);
stream << " {";
lua_pushnil (L); // Initial key
while (lua_next (L, index))
{
stream << "\n";
putIndent (stream, level + 1);
dumpValue (L, -2, stream, level + 1); // Key
stream << ": ";
dumpValue (L, -1, stream, level + 1); // Value
lua_pop (L, 1); // Value
}
putIndent (stream, level);
stream << "\n}";
}
inline void dumpState (lua_State *L, std::ostream& stream = std::cerr)
{
int top = lua_gettop (L);
for (int i = 1; i <= top; ++i)
{
stream << "stack #" << i << ": ";
dumpValue (L, i, stream, 0);
stream << "\n";
}
}
} // namespace debug
} // namespace luabridge

53
lib/lua/piluaprogram.cpp Normal file
View File

@@ -0,0 +1,53 @@
/*
PIP - Platform Independent Primitives
PILuaProgram
Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piluaprogram.h"
PRIVATE_DEFINITION_START(PILuaProgram)
lua_State * lua_state;
PRIVATE_DEFINITION_END(PILuaProgram)
PILuaProgram::PILuaProgram() {
PRIVATE->lua_state = luaL_newstate();
luaL_openlibs(PRIVATE->lua_state);
}
bool PILuaProgram::load(const PIString & script) {
int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8());
if (ret != 0) return false;
return true;
}
bool PILuaProgram::prepare() {
return (lua_pcall(PRIVATE->lua_state, 0, 0, 0) == 0);
}
luabridge::LuaRef PILuaProgram::getGlobal(const PIString & name) {
return luabridge::getGlobal(PRIVATE->lua_state, name.dataUTF8());
}
luabridge::Namespace PILuaProgram::getGlobalNamespace() {
return luabridge::getGlobalNamespace(PRIVATE->lua_state);
}

View File

@@ -4,35 +4,45 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PICloud Client PICloud Client
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PICCLOUDCLIENT_H #ifndef PICCLOUDCLIENT_H
#define PICCLOUDCLIENT_H #define PICCLOUDCLIENT_H
#include "pistring.h" #include "pip_cloud_export.h"
#include "piiodevice.h"
class PIP_EXPORT PICloudClient { class PIEthernet;
class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice
{
PIIODEVICE(PICloudClient)
public: public:
//! //!
PICloudClient(); explicit PICloudClient();
virtual ~PICloudClient();
protected:
bool openDevice();
bool closeDevice();
private: private:
PIEthernet * eth;
}; };
#endif // PICCLOUDCLIENT_H #endif // PICCLOUDCLIENT_H

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Module includes Module includes
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -4,31 +4,33 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PICloud Server PICloud Server
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PICCLOUDSERVER_H #ifndef PICCLOUDSERVER_H
#define PICCLOUDSERVER_H #define PICCLOUDSERVER_H
#include "pistring.h" #include "pip_cloud_export.h"
#include "piiodevice.h"
class PIP_EXPORT PICloudServer {
class PIP_CLOUD_EXPORT PICloudServer {
public: public:
//! //!
PICloudServer(); explicit PICloudServer();
private: private:

View File

@@ -4,28 +4,29 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PICloud TCP transport PICloud TCP transport
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PICCLOUDTCP_H #ifndef PICCLOUDTCP_H
#define PICCLOUDTCP_H #define PICCLOUDTCP_H
#include "pip_cloud_export.h"
#include "pistring.h" #include "pistring.h"
class PIP_EXPORT PICloudTCP { class PIP_CLOUD_EXPORT PICloudTCP {
public: public:
//! //!
PICloudTCP(); PICloudTCP();

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
C++ code info structs C++ code info structs
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
C++ code info structs C++ code info structs
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -24,13 +24,13 @@
#ifndef PICODEINFO_H #ifndef PICODEINFO_H
#define PICODEINFO_H #define PICODEINFO_H
#include "pistring.h" #include "pistringlist.h"
class PIVariant; class PIVariant;
namespace PICodeInfo { namespace PICodeInfo {
enum PIP_EXPORT TypeFlag { enum TypeFlag {
NoFlag, NoFlag,
Const = 0x01, Const = 0x01,
Static = 0x02, Static = 0x02,
@@ -153,10 +153,10 @@ inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) {
return s; return s;
} }
extern PIMap<PIString, PICodeInfo::ClassInfo * > * classesInfo; extern PIP_EXPORT PIMap<PIString, PICodeInfo::ClassInfo * > * classesInfo;
extern PIMap<PIString, PICodeInfo::EnumInfo * > * enumsInfo; extern PIP_EXPORT PIMap<PIString, PICodeInfo::EnumInfo * > * enumsInfo;
extern PIMap<PIString, PICodeInfo::AccessValueFunction> * accessValueFunctions; extern PIP_EXPORT PIMap<PIString, PICodeInfo::AccessValueFunction> * accessValueFunctions;
extern PIMap<PIString, PICodeInfo::AccessTypeFunction> * accessTypeFunctions; extern PIP_EXPORT PIMap<PIString, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) { inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) {
if (!p || !class_name || !member_name || !accessValueFunctions) return PIByteArray(); if (!p || !class_name || !member_name || !accessValueFunctions) return PIByteArray();
@@ -172,11 +172,11 @@ inline const char * getMemberType(const char * class_name, const char * member_n
return af(member_name); return af(member_name);
} }
PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name);
} }
class __PICodeInfoInitializer__ { class PIP_EXPORT __PICodeInfoInitializer__ {
public: public:
__PICodeInfoInitializer__() { __PICodeInfoInitializer__() {
if (_inited_) return; if (_inited_) return;

View File

@@ -0,0 +1,26 @@
/*
PIP - Platform Independent Primitives
Module includes
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICODEMODULE_H
#define PICODEMODULE_H
#include "picodeinfo.h"
#include "picodeparser.h"
#endif // PICODEMODULE_H

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
C++ code parser C++ code parser
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -24,7 +24,7 @@
PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
PIStringList arg_vals; PIStringList arg_vals;
while (!args_.isEmpty()) { while (!args_.isEmpty()) {
int ci = args_.find(","), bi = args_.find("("); int ci = args_.find(','), bi = args_.find('(');
if (ci < 0) { if (ci < 0) {
arg_vals << args_; arg_vals << args_;
break; break;
@@ -33,7 +33,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
if (bi >= 0 && bi < ci) { if (bi >= 0 && bi < ci) {
ca = args_.left(args_.takeLeft(bi).toInt()); ca = args_.left(args_.takeLeft(bi).toInt());
ci -= ca.size_s(); bi -= ca.size_s(); ci -= ca.size_s(); bi -= ca.size_s();
ca += "(" + args_.takeRange("(", ")") + ")"; ca += '(' + args_.takeRange('(', ')') + ')';
} else { } else {
ca = args_.takeLeft(ci); ca = args_.takeLeft(ci);
} }
@@ -41,7 +41,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
args_.trim(); args_.takeLeft(1); args_.trim(); args_.trim(); args_.takeLeft(1); args_.trim();
} }
if (args.size() != arg_vals.size()) { if (args.size() != arg_vals.size()) {
piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect") piCout << ("Error: in expansion of macro \"" + name + '(' + args.join(", ") + ")\": expect")
<< args.size() << "arguments but takes" << arg_vals.size() << "!"; << args.size() << "arguments but takes" << arg_vals.size() << "!";
if (ok != 0) *ok = false; if (ok != 0) *ok = false;
return PIString(); return PIString();
@@ -57,7 +57,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(),1)[0]; if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(),1)[0];
if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars
ind--; ind--;
ret.replace(ind, an.size_s() + 1, "\"" + av + "\""); ret.replace(ind, an.size_s() + 1, '\"' + av + '\"');
ind -= an.size_s() - av.size_s() - 1; ind -= an.size_s() - av.size_s() - 1;
continue; continue;
} }
@@ -66,7 +66,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
ind -= an.size_s() - av.size_s(); ind -= an.size_s() - av.size_s();
} }
} }
ret.replaceAll("##", ""); ret.replaceAll(PIStringAscii("##"), "");
if (ok != 0) *ok = true; if (ok != 0) *ok = true;
return ret; return ret;
} }
@@ -99,20 +99,20 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
} }
piCout << "\n\nDefines:"; piCout << "\n\nDefines:";
piForeachC (Define & m, defines) piForeachC (Define & m, defines)
piCout << "define" << m.first << m.second; piCout << PIStringAscii("define") << m.first << m.second;
piCout << "\n\nMacros:"; piCout << "\n\nMacros:";
piForeachC (Macro & m, macros) piForeachC (Macro & m, macros)
piCout << "Macro:" << m.name << m.args << m.value; piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:"; piCout << "\n\nClasses:";
piCout << "\n\nEnums:"; piCout << "\n\nEnums:";
piForeachC (Enum & c, enums) { piForeachC (Enum & c, enums) {
piCout << "enum" << c.name << c.meta; piCout << PIStringAscii("enum") << c.name << c.meta;
piForeachC (EnumeratorInfo & e, c.members) piForeachC (EnumeratorInfo & e, c.members)
piCout << " " << e.name << "=" << e.value << e.meta; piCout << " " << e.name << '=' << e.value << e.meta;
} }
piCout << "\n\nTypedefs:"; piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs) piForeachC (Typedef & c, typedefs)
piCout << "typedef" << c;*/ piCout << PIStringAscii("typedef") << c;*/
} }
@@ -122,19 +122,19 @@ void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes)
parseFileInternal(f, follow_includes); parseFileInternal(f, follow_includes);
/*piCout << "\n\nDefines:"; /*piCout << "\n\nDefines:";
piForeachC (Define & m, defines) piForeachC (Define & m, defines)
piCout << "define" << m.first << m.second; piCout << PIStringAscii("define") << m.first << m.second;
piCout << "\n\nMacros:"; piCout << "\n\nMacros:";
piForeachC (Macro & m, macros) piForeachC (Macro & m, macros)
piCout << "Macro:" << m.name << m.args << m.value; piCout << "Macro:" << m.name << m.args << m.value;
piCout << "\n\nClasses:"; piCout << "\n\nClasses:";
piForeachC (Entity * c, entities) piForeachC (Entity * c, entities)
piCout << "class" << c->name << c->parents; piCout << PIStringAscii("class") << c->name << c->parents;
piCout << "\n\nEnums:"; piCout << "\n\nEnums:";
piForeachC (Enum & c, enums) piForeachC (Enum & c, enums)
piCout << "enum" << c.name << c.members; piCout << PIStringAscii("enum") << c.name << c.members;
piCout << "\n\nTypedefs:"; piCout << "\n\nTypedefs:";
piForeachC (Typedef & c, typedefs) piForeachC (Typedef & c, typedefs)
piCout << "typedef" << c;*/ piCout << PIStringAscii("typedef") << c;*/
} }
@@ -153,7 +153,7 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes
PIFile f(file, PIIODevice::ReadOnly); PIFile f(file, PIIODevice::ReadOnly);
int ii = 0; int ii = 0;
while (!f.isOpened() && ii < (includes.size_s() - 1)) { while (!f.isOpened() && ii < (includes.size_s() - 1)) {
f.setPath(includes[++ii] + "/" + file); f.setPath(includes[++ii] + '/' + file);
//piCout << "try" << f.path(); //piCout << "try" << f.path();
f.open(PIIODevice::ReadOnly); f.open(PIIODevice::ReadOnly);
} }
@@ -186,7 +186,10 @@ void PICodeParser::clear() {
evaluator.clearCustomVariables(); evaluator.clearCustomVariables();
cur_def_vis = Global; cur_def_vis = Global;
anon_num = 0; anon_num = 0;
defines << Define("PICODE", "") << custom_defines; PIStringList defs = PIStringAscii(PICODE_DEFINES).split(",");
piForeachC (PIString & d, defs)
defines << Define(d, "");
defines << Define(PIStringAscii("PICODE"), "") << custom_defines;
} }
@@ -197,9 +200,9 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
PIString pfc, line, ccmn, tmp; PIString pfc, line, ccmn, tmp;
PIMap<PIString, PIString> cchars; PIMap<PIString, PIString> cchars;
/// Remove comments, join multiline "*" and replace "*" to $n (cchars) /// Remove comments, join multiline '*' and replace '*' to $n (cchars)
fc.replaceAll("\r\n", "\n"); fc.replaceAll("\r\n", '\n');
fc.replaceAll("\r", "\n"); fc.replaceAll('\r', '\n');
for (int i = 0; i < fc.size_s() - 1; ++i) { for (int i = 0; i < fc.size_s() - 1; ++i) {
if (fc[i].unicode16Code() >= 255) continue; if (fc[i].unicode16Code() >= 255) continue;
if (i > 0) pc = c; if (i > 0) pc = c;
@@ -207,13 +210,6 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
if (c == '"' && !mlc && pc != '\'') { if (c == '"' && !mlc && pc != '\'') {
if (i > 0) if (fc[i - 1] == '\\') continue; if (i > 0) if (fc[i - 1] == '\\') continue;
cc = !cc; cc = !cc;
/*if (cc) ccs = i;
if (!cc) {
ccmn = "$" + PIString::fromNumber(cchars.size());
cchars[ccmn] = fc.mid(ccs, i - ccs + 1);
fc.replace(ccs, i - ccs + 1, ccmn);
i = ccs - 1 + ccmn.size_s();
}*/
continue; continue;
} }
if (i > 0) if (i > 0)
@@ -227,7 +223,6 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;} if (fc.mid(i, 2) == "*/" && mlc) {mlc = false; fc.cutMid(mls, i - mls + 2); i = mls - 1; continue;}
if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;} if (fc.mid(i, 2) == "//" && !mlc) {ole = fc.find('\n', i); fc.cutMid(i, ole < 0 ? -1 : ole - i); --i; continue;}
} }
//PICout(PICoutManipulators::DefaultControls) << fc;
pfc = procMacros(fc); pfc = procMacros(fc);
replaceMeta(pfc); replaceMeta(pfc);
@@ -264,7 +259,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(),1)[0]; if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(),1)[0];
if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue; if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue;
PIString ret, range; bool ok(false); PIString ret, range; bool ok(false);
range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")"); range = pfc.mid(ind + m.name.size_s()).takeRange('(', ')');
ret = m.expand(range, &ok); ret = m.expand(range, &ok);
if (!ok) return false; if (!ok) return false;
int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind; int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind;
@@ -282,46 +277,46 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
int nl = pfc.size_s(); int nl = pfc.size_s();
if (pl == nl) break; if (pl == nl) break;
pl = nl; pl = nl;
if (pfc.left(9) == "namespace") { if (pfc.left(9) == PIStringAscii("namespace")) {
pfc.cutLeft(pfc.find("{") + 1); pfc.cutLeft(pfc.find('{') + 1);
continue; continue;
} }
if (pfc.left(8) == "template") { if (pfc.left(8) == PIStringAscii("template")) {
pfc.cutLeft(8); pfc.cutLeft(8);
pfc.takeRange("<", ">"); pfc.takeRange('<', '>');
bool def = !isDeclaration(pfc, 0, &end); bool def = !isDeclaration(pfc, 0, &end);
pfc.cutLeft(end); pfc.cutLeft(end);
if (def) pfc.takeRange("{", "}"); if (def) pfc.takeRange('{', '}');
else pfc.takeSymbol(); else pfc.takeSymbol();
continue; continue;
} }
if (pfc.left(5) == "class" || pfc.left(6) == "struct" || pfc.left(5) == "union") { if (pfc.left(5) == PIStringAscii("class") || pfc.left(6) == PIStringAscii("struct") || pfc.left(5) == PIStringAscii("union")) {
int dind = pfc.find("{", 0), find = pfc.find(";", 0); int dind = pfc.find('{', 0), find = pfc.find(';', 0);
if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;} if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;}
if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;} if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;}
ccmn = pfc.left(dind) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n"; ccmn = pfc.left(dind) + PIStringAscii("{\n") + pfc.mid(dind).takeRange('{', '}') + PIStringAscii("\n}\n");
pfc.remove(0, ccmn.size()); pfc.remove(0, ccmn.size());
parseClass(0, ccmn); parseClass(0, ccmn);
continue; continue;
} }
if (pfc.left(4) == "enum") { if (pfc.left(4) == PIStringAscii("enum")) {
pfc.cutLeft(4); pfc.cutLeft(4);
tmp = pfc.takeCWord(); tmp = pfc.takeCWord();
pfc.trim(); pfc.trim();
MetaMap meta = maybeMeta(pfc); MetaMap meta = maybeMeta(pfc);
parseEnum(0, cur_namespace + tmp, pfc.takeRange("{", "}"), meta); parseEnum(0, cur_namespace + tmp, pfc.takeRange('{', '}'), meta);
pfc.takeSymbol(); pfc.takeSymbol();
continue; continue;
} }
if (pfc.left(7) == "typedef") { if (pfc.left(7) == PIStringAscii("typedef")) {
pfc.cutLeft(7); pfc.cutLeft(7);
typedefs << parseTypedef(pfc.takeLeft(pfc.find(";"))); typedefs << parseTypedef(pfc.takeLeft(pfc.find(';')));
if (typedefs.back().first.isEmpty()) typedefs.pop_back(); if (typedefs.back().first.isEmpty()) typedefs.pop_back();
else root_.typedefs << typedefs.back(); else root_.typedefs << typedefs.back();
pfc.takeSymbol(); pfc.takeSymbol();
continue; continue;
} }
int sci = pfc.find(";", 0), obi = pfc.find("{", 0); int sci = pfc.find(';', 0), obi = pfc.find('{', 0);
if (sci < 0 && obi < 0) { if (sci < 0 && obi < 0) {
pfc.takeLeft(1); pfc.takeLeft(1);
continue; continue;
@@ -331,7 +326,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
str = pfc.takeLeft(sci + 1); str = pfc.takeLeft(sci + 1);
} else { } else {
str = pfc.takeLeft(obi); str = pfc.takeLeft(obi);
pfc.cutLeft(pfc.takeRange("{", "}").toInt()); pfc.cutLeft(pfc.takeRange('{', '}').toInt());
} }
parseMember(&root_, str); parseMember(&root_, str);
} }
@@ -341,22 +336,22 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) { PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) {
PIString cd = fc.trimmed().removeAll('\n').replaceAll("\t", " ").replaceAll(" ", " "), pn; PIString cd = fc.trimmed().removeAll('\n').replaceAll('\t', ' ').replaceAll(PIStringAscii(" "), ' '), pn;
MetaMap meta; MetaMap meta;
int ind = cd.find("$M"); int ind = cd.find(PIStringAscii("$M"));
if (ind >= 0) { if (ind >= 0) {
meta = tmp_meta.value(cd.takeMid(ind, 5)); meta = tmp_meta.value(cd.takeMid(ind, 5));
cd.replaceAll(" ", " "); cd.replaceAll(PIStringAscii(" "), ' ');
} }
//piCout << "found class <****\n" << cd << "\n****>"; //piCout << "found class <****\n" << cd << "\n****>";
ind = cd.find(":"); ind = cd.find(':');
PIVector<Entity * > parents; PIVector<Entity * > parents;
if (ind > 0) { if (ind > 0) {
PIStringList pl = cd.takeMid(ind + 1).trim().split(","); PIStringList pl = cd.takeMid(ind + 1).trim().split(',');
cd.cutRight(1); cd.cutRight(1);
Entity * pe = 0; Entity * pe = 0;
piForeachC (PIString & p, pl) { piForeachC (PIString & p, pl) {
if (p.contains(" ")) pn = p.mid(p.find(" ") + 1); if (p.contains(' ')) pn = p.mid(p.find(' ') + 1);
else pn = p; else pn = p;
pe = findEntityByName(pn); pe = findEntityByName(pn);
if (pe == 0) ;//{piCout << "Error: can`t find" << pn;} if (pe == 0) ;//{piCout << "Error: can`t find" << pn;}
@@ -364,17 +359,17 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
} }
} }
PIString typename_ = cd.left(6).trim(); PIString typename_ = cd.left(6).trim();
bool is_class = typename_ == "class"; bool is_class = typename_ == PIStringAscii("class");
cur_def_vis = (is_class ? Private : Public); cur_def_vis = (is_class ? Private : Public);
PIString cn = cd.mid(6).trim(); PIString cn = cd.mid(6).trim();
bool has_name = !cn.isEmpty(); bool has_name = !cn.isEmpty();
if (cn.isEmpty()) cn = "<unnamed_" + PIString::fromNumber(anon_num++) + ">"; if (cn.isEmpty()) cn = PIStringAscii("<unnamed_") + PIString::fromNumber(anon_num++) + '>';
//piCout << "found " << typename_ << cn; //piCout << "found " << typename_ << cn;
if (cn.isEmpty()) return 0; if (cn.isEmpty()) return 0;
Entity * e = new Entity(); Entity * e = new Entity();
e->meta = meta; e->meta = meta;
e->name = cur_namespace + cn; e->name = cur_namespace + cn;
e->type = typename_;//(is_class ? "class" : "struct"); e->type = typename_;
e->has_name = has_name; e->has_name = has_name;
e->parents = parents; e->parents = parents;
e->file = cur_file; e->file = cur_file;
@@ -385,7 +380,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
Visibility prev_vis = cur_def_vis; Visibility prev_vis = cur_def_vis;
int dind = fc.find("{"), find = fc.find(";"), end = 0; int dind = fc.find('{'), find = fc.find(';'), end = 0;
if (dind < 0 && find < 0) return PIString(); if (dind < 0 && find < 0) return PIString();
if (dind < 0 || find < dind) return fc.left(find); if (dind < 0 || find < dind) return fc.left(find);
//piCout << "parse class <****\n" << fc.left(20) << "\n****>"; //piCout << "parse class <****\n" << fc.left(20) << "\n****>";
@@ -398,43 +393,43 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
int ps = -1; int ps = -1;
bool def = false; bool def = false;
PIString prev_namespace = cur_namespace, stmp; PIString prev_namespace = cur_namespace, stmp;
cur_namespace = ce->name + "::"; cur_namespace = ce->name + PIStringAscii("::");
//piCout << "parse class" << ce->name << "namespace" << cur_namespace; //piCout << "parse class" << ce->name << "namespace" << cur_namespace;
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace; //piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
while (!fc.isEmpty()) { while (!fc.isEmpty()) {
PIString cw = fc.takeCWord(), tmp; PIString cw = fc.takeCWord(), tmp;
//piCout << "\ntaked word" << cw; //piCout << "\ntaked word" << cw;
if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;} if (cw == PIStringAscii("public" )) {cur_def_vis = Public; fc.cutLeft(1); continue;}
if (cw == "protected") {cur_def_vis = Protected; fc.cutLeft(1); continue;} if (cw == PIStringAscii("protected")) {cur_def_vis = Protected; fc.cutLeft(1); continue;}
if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;} if (cw == PIStringAscii("private" )) {cur_def_vis = Private; fc.cutLeft(1); continue;}
if (cw == "class" || cw == "struct" || cw == "union") { if (cw == PIStringAscii("class") || cw == PIStringAscii("struct") || cw == PIStringAscii("union")) {
if (isDeclaration(fc, 0, &end)) { if (isDeclaration(fc, 0, &end)) {
fc.cutLeft(end); fc.cutLeft(end);
fc.takeSymbol(); fc.takeSymbol();
continue; continue;
} }
tmp = fc.takeLeft(fc.find("{")); tmp = fc.takeLeft(fc.find('{'));
stmp = fc.takeRange("{", "}"); stmp = fc.takeRange('{', '}');
fc.takeSymbol(); fc.takeSymbol();
stmp = cw + " " + tmp + "{" + stmp + "}"; stmp = cw + ' ' + tmp + '{' + stmp + '}';
parseClass(ce, stmp); parseClass(ce, stmp);
continue; continue;
} }
if (cw == "enum") { if (cw == PIStringAscii("enum")) {
tmp = fc.takeCWord(); tmp = fc.takeCWord();
fc.trim(); fc.trim();
MetaMap meta = maybeMeta(fc); MetaMap meta = maybeMeta(fc);
parseEnum(ce, cur_namespace + tmp, fc.takeRange("{", "}"), meta); parseEnum(ce, cur_namespace + tmp, fc.takeRange('{', '}'), meta);
fc.takeSymbol(); fc.takeSymbol();
continue; continue;
} }
if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;} if (cw == PIStringAscii("friend")) {fc.cutLeft(fc.find(';') + 1); continue;}
if (cw == "typedef") {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(";"))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;} if (cw == PIStringAscii("typedef")) {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';'))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;}
if (cw == "template") { if (cw == PIStringAscii("template")) {
fc.takeRange("<", ">"); fc.takeRange('<', '>');
def = !isDeclaration(fc, 0, &end); def = !isDeclaration(fc, 0, &end);
fc.cutLeft(end); fc.cutLeft(end);
if (def) fc.takeRange("{", "}"); if (def) fc.takeRange('{', '}');
else fc.takeSymbol(); else fc.takeSymbol();
continue; continue;
} }
@@ -442,9 +437,9 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
tmp = (cw + fc.takeLeft(end)).trim(); tmp = (cw + fc.takeLeft(end)).trim();
if (!tmp.isEmpty()) if (!tmp.isEmpty())
parseMember(ce, tmp); parseMember(ce, tmp);
if (def) fc.takeRange("{", "}"); if (def) fc.takeRange('{', '}');
else fc.takeSymbol(); else fc.takeSymbol();
if (ps == fc.size_s()) {/*cur_namespace = prev_namespace;*/ fc.cutLeft(1);/*return false*/;} if (ps == fc.size_s()) {fc.cutLeft(1);}
ps = fc.size_s(); ps = fc.size_s();
} }
cur_def_vis = prev_vis; cur_def_vis = prev_vis;
@@ -456,13 +451,13 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) {
PICodeParser::MetaMap ret; PICodeParser::MetaMap ret;
if (fc.isEmpty()) return ret; if (fc.isEmpty()) return ret;
PIStringList ml = fc.split(","); PIStringList ml = fc.split(',');
piForeachC (PIString & m, ml) { piForeachC (PIString & m, ml) {
int i = m.find("="); int i = m.find('=');
if (i < 0) continue; if (i < 0) continue;
PIString mv = m.mid(i + 1).trim(); PIString mv = m.mid(i + 1).trim();
if (mv.startsWith("\"")) mv.cutLeft(1); if (mv.startsWith('\"')) mv.cutLeft(1);
if (mv.endsWith("\"")) mv.cutRight(1); if (mv.endsWith('\"')) mv.cutRight(1);
ret[m.left(i).trim()] = mv; ret[m.left(i).trim()] = mv;
} }
//piCout << ms << ret; //piCout << ms << ret;
@@ -471,20 +466,22 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) {
bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta) { bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta) {
//piCout << "enum" << name << fc; static const PIString s_ss = PIStringAscii(" ");
static const PIString s_M = PIStringAscii("$M");
//piCout << PIStringAscii("enum") << name << fc;
Enum e(name); Enum e(name);
e.meta = meta; e.meta = meta;
PIStringList vl(fc.split(",")); PIStringList vl(fc.split(','));
PIString vn; PIString vn;
int cv = -1, ind = 0; int cv = -1, ind = 0;
piForeach (PIString & v, vl) { piForeach (PIString & v, vl) {
MetaMap meta; MetaMap meta;
int mi = v.find("$M"); int mi = v.find(s_M);
if (mi >= 0) { if (mi >= 0) {
meta = tmp_meta.value(v.takeMid(mi, 5)); meta = tmp_meta.value(v.takeMid(mi, 5));
v.replaceAll(" ", " "); v.replaceAll(s_ss, ' ');
} }
vn = v; ind = v.find("="); vn = v; ind = v.find('=');
if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);} if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);}
if (ind < 0) ++cv; if (ind < 0) ++cv;
e.members << EnumeratorInfo(vn.trim(), cv, meta); e.members << EnumeratorInfo(vn.trim(), cv, meta);
@@ -500,15 +497,15 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc
PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) { PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
//piCout << "parse typedef" << fc; //piCout << "parse typedef" << fc;
Typedef td; Typedef td;
fc.replaceAll("\t", " "); fc.replaceAll('\t', ' ');
if (fc.contains("(")) { if (fc.contains('(')) {
int start = fc.find("("), end = fc.find(")"); int start = fc.find('('), end = fc.find(')');
td.first = fc.takeMid(start + 1, end - start - 1).trim(); td.first = fc.takeMid(start + 1, end - start - 1).trim();
if (td.first.left(1) == "*") {td.first.cutLeft(1).trim(); fc.insert(start + 1, "*");} if (td.first.left(1) == PIChar('*')) {td.first.cutLeft(1).trim(); fc.insert(start + 1, '*');}
td.second = fc.trim(); td.second = fc.trim();
} else { } else {
td.first = fc.takeMid(fc.findLast(" ")).trim(); td.first = fc.takeMid(fc.findLast(' ')).trim();
td.second = fc.trim(); td.second = fc.trim();
} }
//piCout << "found typedef" << td; //piCout << "found typedef" << td;
@@ -517,34 +514,53 @@ PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
bool PICodeParser::parseMember(Entity * parent, PIString & fc) { bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
static const PIString s_operator = PIStringAscii("operator");
static const PIString s_ss = PIStringAscii(" ");
static const PIString s_cs = PIStringAscii(", ");
static const PIString s_sb = PIStringAscii(" (");
static const PIString s_sM = PIStringAscii(" $M");
static const PIString s_M = PIStringAscii("$M");
static const PIString s_T = PIStringAscii("$T");
static const PIString s_inline_s = PIStringAscii("inline ");
static const PIString s_static_s = PIStringAscii("static ");
static const PIString s_virtual_s = PIStringAscii("virtual ");
static const PIString s_void = PIStringAscii("void");
static const PIString s_using = PIStringAscii("using");
static const PIString s_s5 = PIStringAscii(" ");
static const PIString s_s_const_s = PIStringAscii(" const ");
static const PIString s_s_static_s = PIStringAscii(" static ");
static const PIString s_s_mutable_s = PIStringAscii(" mutable ");
static const PIString s_s_volatile_s = PIStringAscii(" volatile ");
static const PIString s_s_extern_s = PIStringAscii(" extern ");
if (fc.trim().isEmpty()) return true; if (fc.trim().isEmpty()) return true;
if (fc.find("operator") >= 0) return true; if (fc.find(s_operator) >= 0) return true;
tmp_temp.clear(); tmp_temp.clear();
//piCout << "parse member" << fc; //piCout << "parse member" << fc;
int ts = fc.find("<"), te = 0; int ts = fc.find('<'), te = 0;
PIString ctemp, crepl; PIString ctemp, crepl;
while (ts >= 0) { while (ts >= 0) {
ctemp = fc.mid(ts).takeRange("<", ">"); ctemp = fc.mid(ts).takeRange('<', '>');
if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find("<", te); continue;} if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find('<', te); continue;}
crepl = "$T" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0"); crepl = s_T + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, '0');
fc.replace(ts, ctemp.size_s() + 2, crepl); fc.replace(ts, ctemp.size_s() + 2, crepl);
tmp_temp[crepl] = "<" + ctemp + ">"; tmp_temp[crepl] = '<' + ctemp + '>';
ts = fc.find("<", te); ts = fc.find('<', te);
} }
fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",").replaceAll(" (", "(").replaceAll(" $M", "$M"); fc.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll(s_ss, ' ').replaceAll(s_cs, ',').replaceAll(s_sb, '(').replaceAll(s_sM, s_M);
//piCout << "parse member" << fc; //piCout << "parse member" << fc;
PIStringList tl, al; PIStringList tl, al;
Member me; Member me;
//piCout << fc; //piCout << fc;
if (fc.contains("(")) { if (fc.contains('(')) {
MetaMap meta; MetaMap meta;
int ind = fc.find("$M"); int ind = fc.find(s_M);
if (ind >= 0) { if (ind >= 0) {
meta = tmp_meta.value(fc.takeMid(ind, 5)); meta = tmp_meta.value(fc.takeMid(ind, 5));
fc.replaceAll(" ", " ").replaceAll(" (", "("); fc.replaceAll(s_ss, ' ').replaceAll(s_sb, '(');
} }
fc.cutRight(fc.size_s() - fc.findLast(")") - 1); fc.cutRight(fc.size_s() - fc.findLast(')') - 1);
te = fc.find("("); te = fc.find('(');
//piCout << fc; //piCout << fc;
for (ts = te - 1; ts >= 0; --ts) for (ts = te - 1; ts >= 0; --ts)
if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break; if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break;
@@ -552,37 +568,37 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
me.meta = meta; me.meta = meta;
me.name = fc.takeMid(ts + 1, te - ts - 1); me.name = fc.takeMid(ts + 1, te - ts - 1);
if (me.name == parent->name) return true; if (me.name == parent->name) return true;
me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(","); me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(',');
me.type = fc.cutRight(1).trim(); me.type = fc.cutRight(1).trim();
me.visibility = cur_def_vis; me.visibility = cur_def_vis;
if (me.type.find("inline ") >= 0) { if (me.type.find(s_inline_s) >= 0) {
me.attributes |= Inline; me.attributes |= Inline;
me.type.removeAll("inline "); me.type.removeAll(s_inline_s);
} }
if (me.type.find("static ") >= 0) { if (me.type.find(s_static_s) >= 0) {
me.attributes |= Static; me.attributes |= Static;
me.type.removeAll("static "); me.type.removeAll(s_static_s);
} }
if (me.type.find("virtual ") >= 0) { if (me.type.find(s_virtual_s) >= 0) {
me.attributes |= Virtual; me.attributes |= Virtual;
me.type.removeAll("virtual "); me.type.removeAll(s_virtual_s);
} }
normalizeEntityNamespace(me.type); normalizeEntityNamespace(me.type);
int i = 0; int i = 0;
//piCout << me.arguments_full; //piCout << me.arguments_full;
piForeach (PIString & a, me.arguments_full) piForeach (PIString & a, me.arguments_full)
if ((i = a.find("=")) > 0) if ((i = a.find('=')) > 0)
a.cutRight(a.size_s() - i).trim(); a.cutRight(a.size_s() - i).trim();
for (int j = 0; j < me.arguments_full.size_s(); ++j) for (int j = 0; j < me.arguments_full.size_s(); ++j)
if (me.arguments_full[j] == "void") { if (me.arguments_full[j] == s_void) {
me.arguments_full.remove(j); me.arguments_full.remove(j);
--j; --j;
} }
me.arguments_type = me.arguments_full; me.arguments_type = me.arguments_full;
piForeach (PIString & a, me.arguments_type) { piForeach (PIString & a, me.arguments_type) {
crepl.clear(); crepl.clear();
if (a.contains("[")) if (a.contains('['))
crepl = a.takeMid(a.find("["), a.findLast("]") - a.find("[") + 1); crepl = a.takeMid(a.find('['), a.findLast(']') - a.find('[') + 1);
for (ts = a.size_s() - 1; ts >= 0; --ts) for (ts = a.size_s() - 1; ts >= 0; --ts)
if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break; if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break;
a.cutRight(a.size_s() - ts - 1); a.cutRight(a.size_s() - ts - 1);
@@ -594,18 +610,18 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
//piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type; //piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type;
parent->functions << me; parent->functions << me;
} else { } else {
if (fc.endsWith(";")) fc.cutRight(1); if (fc.endsWith(';')) fc.cutRight(1);
if (fc.startsWith("using") || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; if (fc.startsWith(s_using) || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true;
int bits = extractMemberBits(fc); int bits = extractMemberBits(fc);
tl = fc.split(","); tl = fc.split(',');
//piCout << "member" << fc << tl; //piCout << "member" << fc << tl;
//piCout << "member after eb" << fc << ", bits =" << bits; //piCout << "member after eb" << fc << ", bits =" << bits;
if (tl.isEmpty()) return true; if (tl.isEmpty()) return true;
bool vn = true; bool vn = true;
ctemp = tl.front().trim(); ctemp = tl.front().trim();
PIString meta_t; PIString meta_t;
if (ctemp.contains("$M")) if (ctemp.contains(s_M))
meta_t = ctemp.takeMid(ctemp.find("$M")); meta_t = ctemp.takeMid(ctemp.find(s_M));
for (ts = ctemp.size_s() - 1; ts > 0; --ts) { for (ts = ctemp.size_s() - 1; ts > 0; --ts) {
if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;} if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;}
else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;} else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;}
@@ -614,26 +630,26 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
me.visibility = cur_def_vis; me.visibility = cur_def_vis;
ctemp += meta_t; ctemp += meta_t;
restoreTmpTemp(&me); restoreTmpTemp(&me);
PIString type = " " + me.type; PIString type = s_s5 + me.type;
if (type.find(" const ") >= 0) { if (type.find(s_s_const_s) >= 0) {
me.attributes |= Const; me.attributes |= Const;
type.replaceAll(" const ", " "); type.replaceAll(s_s_const_s, ' ');
} }
if (type.find(" static ") >= 0) { if (type.find(s_s_static_s) >= 0) {
me.attributes |= Static; me.attributes |= Static;
type.replaceAll(" static ", " "); type.replaceAll(s_s_static_s, ' ');
} }
if (type.find(" mutable ") >= 0) { if (type.find(s_s_mutable_s) >= 0) {
me.attributes |= Mutable; me.attributes |= Mutable;
type.replaceAll(" mutable ", " "); type.replaceAll(s_s_mutable_s, ' ');
} }
if (type.find(" volatile ") >= 0) { if (type.find(s_s_volatile_s) >= 0) {
me.attributes |= Volatile; me.attributes |= Volatile;
type.replaceAll(" volatile ", " "); type.replaceAll(s_s_volatile_s, ' ');
} }
if (type.find(" extern ") >= 0) { if (type.find(s_s_extern_s) >= 0) {
me.attributes |= Extern; me.attributes |= Extern;
type.replaceAll(" extern ", " "); type.replaceAll(s_s_extern_s, ' ');
} }
type.trim(); type.trim();
normalizeEntityNamespace(type); normalizeEntityNamespace(type);
@@ -645,15 +661,15 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
me.type = type; me.type = type;
restoreTmpMeta(&me); restoreTmpMeta(&me);
if (me.name.isEmpty()) continue; if (me.name.isEmpty()) continue;
if (me.name.contains("[")) if (me.name.contains('['))
crepl = me.name.takeMid(me.name.find("["), me.name.findLast("]") - me.name.find("[") + 1); crepl = me.name.takeMid(me.name.find('['), me.name.findLast(']') - me.name.find('[') + 1);
while (!me.name.isEmpty()) { while (!me.name.isEmpty()) {
if (me.name.front() == "*" || me.name.front() == "&") { if (me.name.front() == PIChar('*') || me.name.front() == PIChar('&')) {
me.type += me.name.takeLeft(1); me.type += me.name.takeLeft(1);
me.name.trim(); me.name.trim();
} else break; } else break;
} }
me.is_type_ptr = (me.type.right(1) == "]" || me.type.right(1) == "*"); me.is_type_ptr = (me.type.right(1) == PIChar(']') || me.type.right(1) == PIChar('*'));
me.type += crepl; me.type += crepl;
me.bits = bits; me.bits = bits;
while (!crepl.isEmpty()) { while (!crepl.isEmpty()) {
@@ -672,7 +688,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) {
int PICodeParser::extractMemberBits(PIString & fc) { int PICodeParser::extractMemberBits(PIString & fc) {
int i = fc.findLast(":"); int i = fc.findLast(':');
if (i <= 0) return -1; if (i <= 0) return -1;
if (fc[i - 1].toAscii() == ':') return -1; if (fc[i - 1].toAscii() == ':') return -1;
PIString bs = fc.takeMid(i).mid(1).trim(); PIString bs = fc.takeMid(i).mid(1).trim();
@@ -682,6 +698,14 @@ int PICodeParser::extractMemberBits(PIString & fc) {
void PICodeParser::normalizeEntityNamespace(PIString & n) { void PICodeParser::normalizeEntityNamespace(PIString & n) {
static const PIString s_const_s = PIStringAscii("const ");
static const PIString s_static_s = PIStringAscii("static ");
static const PIString s_mutable_s = PIStringAscii("mutable ");
static const PIString s_volatile_s = PIStringAscii("volatile ");
static const PIString s_s_const_s = PIStringAscii(" const ");
static const PIString s_s_static_s = PIStringAscii(" static ");
static const PIString s_s_mutable_s = PIStringAscii(" mutable ");
static const PIString s_s_volatile_s = PIStringAscii(" volatile ");
PIString suff, pref; PIString suff, pref;
for (int i = n.size_s() - 1; i > 0; --i) for (int i = n.size_s() - 1; i > 0; --i)
if (_isCChar(n[i]) || n[i].isDigit()) { if (_isCChar(n[i]) || n[i].isDigit()) {
@@ -689,11 +713,11 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
n.cutRight(suff.size_s()); n.cutRight(suff.size_s());
break; break;
} }
n.push_front(" "); n.push_front(' ');
if (n.find(" static ") >= 0) {n.replaceAll(" static ", ""); pref += "static ";} if (n.find(s_s_const_s) >= 0) {n.replaceAll(s_s_const_s, ""); pref += s_const_s;}
if (n.find(" const ") >= 0) {n.replaceAll(" const ", ""); pref += "const ";} if (n.find(s_s_static_s) >= 0) {n.replaceAll(s_s_static_s, ""); pref += s_static_s;}
if (n.find(" mutable ") >= 0) {n.replaceAll(" mutable ", ""); pref += "mutable ";} if (n.find(s_s_mutable_s) >= 0) {n.replaceAll(s_s_mutable_s, ""); pref += s_mutable_s;}
if (n.find(" volatile ") >= 0) {n.replaceAll(" volatile ", ""); pref += "volatile ";} if (n.find(s_s_volatile_s) >= 0) {n.replaceAll(s_s_volatile_s, ""); pref += s_volatile_s;}
n.trim(); n.trim();
int f = 0; int f = 0;
piForeachC (Entity * e, entities) { piForeachC (Entity * e, entities) {
@@ -702,28 +726,30 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
return; return;
} }
if ((f = e->name.find(n)) >= 0) if ((f = e->name.find(n)) >= 0)
if (e->name.mid(f - 1, 1) == ":") if (e->name.at(f - 1) == PIChar(':'))
if (e->name.find(cur_namespace) >= 0) { if (e->name.find(cur_namespace) >= 0) {
n = pref + e->name + suff; n = pref + e->name + suff;
return; return;
} }
} }
piForeachC (Enum & e, enums) piForeachC (Enum & e, enums) {
if ((f = e.name.find(n)) >= 0) if ((f = e.name.find(n)) >= 0)
if (e.name.mid(f - 1, 1) == ":") if (e.name.at(f - 1) == PIChar(':'))
if (e.name.find(cur_namespace) >= 0) { if (e.name.find(cur_namespace) >= 0) {
//piCout << "change" << n << "to" << e.name + suff; //piCout << "change" << n << "to" << e.name + suff;
n = pref + e.name + suff; n = pref + e.name + suff;
return; return;
} }
piForeachC (Typedef & e, typedefs) }
piForeachC (Typedef & e, typedefs) {
if ((f = e.first.find(n)) >= 0) if ((f = e.first.find(n)) >= 0)
if (e.first.mid(f - 1, 1) == ":") if (e.first.at(f - 1) == PIChar(':'))
if (e.first.find(cur_namespace) >= 0) { if (e.first.find(cur_namespace) >= 0) {
//piCout << "change" << n << "to" << e.name + suff; //piCout << "change" << n << "to" << e.name + suff;
n = pref + e.first + suff; n = pref + e.first + suff;
return; return;
} }
}
n = (pref + n + suff).trim(); n = (pref + n + suff).trim();
} }
@@ -731,20 +757,20 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) {
void PICodeParser::restoreTmpTemp(Member * e) { void PICodeParser::restoreTmpTemp(Member * e) {
int i = 0; int i = 0;
piForeach (PIString & a, e->arguments_full) { piForeach (PIString & a, e->arguments_full) {
while ((i = a.find("$T")) >= 0) while ((i = a.find(PIStringAscii("$T"))) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]); a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
} }
piForeach (PIString & a, e->arguments_type) { piForeach (PIString & a, e->arguments_type) {
while ((i = a.find("$T")) >= 0) while ((i = a.find(PIStringAscii("$T"))) >= 0)
a.replace(i, 5, tmp_temp[a.mid(i, 5)]); a.replace(i, 5, tmp_temp[a.mid(i, 5)]);
} }
while ((i = e->type.find("$T")) >= 0) while ((i = e->type.find(PIStringAscii("$T"))) >= 0)
e->type.replace(i, 5, tmp_temp[e->type.mid(i, 5)]); e->type.replace(i, 5, tmp_temp[e->type.mid(i, 5)]);
} }
void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) { void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) {
int i = e->name.find("$M"); int i = e->name.find(PIStringAscii("$M"));
if (i < 0) return; if (i < 0) return;
e->meta = tmp_meta[e->name.takeMid(i, 5)]; e->meta = tmp_meta[e->name.takeMid(i, 5)];
} }
@@ -752,7 +778,7 @@ void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) {
PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) { PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) {
PICodeParser::MetaMap ret; PICodeParser::MetaMap ret;
if (fc.left(2) == "$M") { if (fc.left(2) == PIStringAscii("$M")) {
ret = tmp_meta.value(fc.takeLeft(5)); ret = tmp_meta.value(fc.takeLeft(5));
fc.trim(); fc.trim();
} }
@@ -762,10 +788,10 @@ PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) {
bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) { bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) {
//piCout << "macroCondition" << mif << mifcond; //piCout << "macroCondition" << mif << mifcond;
if (mif == "ifdef") return isDefineExists(mifcond); if (mif == PIStringAscii("ifdef")) return isDefineExists(mifcond);
if (mif == "ifndef") return !isDefineExists(mifcond); if (mif == PIStringAscii("ifndef")) return !isDefineExists(mifcond);
if (mif == "if" || mif == "elif") { if (mif == PIStringAscii("if") || mif == PIStringAscii("elif")) {
mifcond.removeAll(" ").removeAll("\t"); mifcond.removeAll(' ').removeAll('\t');
return procMacrosCond(mifcond) > 0.; return procMacrosCond(mifcond) > 0.;
} }
return false; return false;
@@ -778,7 +804,7 @@ double PICodeParser::procMacrosCond(PIString fc) {
int oper = 0, ps = -1; int oper = 0, ps = -1;
char cc, nc; char cc, nc;
PIString ce; PIString ce;
fc.removeAll("defined"); fc.removeAll(PIStringAscii("defined"));
//piCout << "procMacrosCond" << fc; //piCout << "procMacrosCond" << fc;
while (!fc.isEmpty()) { while (!fc.isEmpty()) {
cc = fc[0].toAscii(); cc = fc[0].toAscii();
@@ -833,17 +859,17 @@ double PICodeParser::defineValue(const PIString & dn) {
void PICodeParser::replaceMeta(PIString & dn) { void PICodeParser::replaceMeta(PIString & dn) {
tmp_meta.clear(); tmp_meta.clear();
if (dn.isEmpty()) return; if (dn.isEmpty()) return;
int s = dn.find("PIMETA"); int s = dn.find(PIStringAscii("PIMETA"));
while (s >= 0) { while (s >= 0) {
int ms = 0, ml = 0; int ms = 0, ml = 0;
ms = dn.findRange('(', ')', '\\', s + 6, &ml); ms = dn.findRange('(', ')', '\\', s + 6, &ml);
if (ms < 0) return; if (ms < 0) return;
PIString meta = dn.mid(ms, ml).trim(); PIString meta = dn.mid(ms, ml).trim();
PIString rm = "$M" + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, "0"); PIString rm = PIStringAscii("$M") + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, '0');
dn.replace(s, ms + ml + 1 - s, rm); dn.replace(s, ms + ml + 1 - s, rm);
//piCout << "FOUND META \"" << meta << "\""; //piCout << "FOUND META \"" << meta << '\"';
tmp_meta[rm] = parseMeta(meta); tmp_meta[rm] = parseMeta(meta);
s = dn.find("PIMETA"); s = dn.find(PIStringAscii("PIMETA"));
} }
} }
@@ -857,7 +883,7 @@ PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) { bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) {
int dind = fc.find("{", start), find = fc.find(";", start); int dind = fc.find('{', start), find = fc.find(';', start);
//piCout << "isDeclaration" << dind << find << fc.left(10); //piCout << "isDeclaration" << dind << find << fc.left(10);
if (dind < 0 && find < 0) {if (end) *end = -1; return true;} if (dind < 0 && find < 0) {if (end) *end = -1; return true;}
if (dind < 0 || find < dind) {if (end) *end = find; return true;} if (dind < 0 || find < dind) {if (end) *end = find; return true;}
@@ -869,17 +895,17 @@ bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) {
bool PICodeParser::isMainFile(const PIString & fc) { bool PICodeParser::isMainFile(const PIString & fc) {
int si = 0; int si = 0;
while (si >= 0) { while (si >= 0) {
int csi = fc.find(" main", si); int csi = fc.find(PIStringAscii(" main"), si);
if (csi < 0) csi = fc.find("\tmain", si); if (csi < 0) csi = fc.find(PIStringAscii("\tmain"), si);
if (csi < 0) csi = fc.find("\nmain", si); if (csi < 0) csi = fc.find(PIStringAscii("\nmain"), si);
if (csi < 0) return false; if (csi < 0) return false;
si = csi; si = csi;
int fi = fc.find("(", si + 5); int fi = fc.find('(', si + 5);
if (fi < 0) return false; if (fi < 0) return false;
if (fi - si < 10) { if (fi - si < 10) {
PIString ms(fc.mid(si, fi - si + 1)); PIString ms(fc.mid(si, fi - si + 1));
ms.removeAll(" ").removeAll("\t").removeAll("\n"); ms.removeAll(' ').removeAll('\t').removeAll('\n');
if (ms == "main(") return true; if (ms == PIStringAscii("main(")) return true;
} }
si += 5; si += 5;
} }
@@ -893,17 +919,17 @@ PIString PICodeParser::procMacros(PIString fc) {
bool grab = false, skip = false, cond_ok = false; bool grab = false, skip = false, cond_ok = false;
PIString pfc, nfc, line, mif, mifcond; PIString pfc, nfc, line, mif, mifcond;
//piCout << "procMacros\n<******" << fc << "\n******>"; //piCout << "procMacros\n<******" << fc << "\n******>";
fc += "\n"; fc += '\n';
while (!fc.isEmpty()) { while (!fc.isEmpty()) {
line = fc.takeLine().trimmed(); line = fc.takeLine().trimmed();
if (line.left(1) == "#") { if (line.left(1) == PIChar('#')) {
mifcond = line.mid(1); mifcond = line.mid(1);
mif = mifcond.takeCWord(); mif = mifcond.takeCWord();
//piCout << mif; //piCout << mif;
//piCout << "mif mifcond" << mif << mifcond << ifcnt; //piCout << "mif mifcond" << mif << mifcond << ifcnt;
if (skip || grab) { if (skip || grab) {
if (mif.left(2) == "if") ifcnt++; if (mif.left(2) == PIStringAscii("if")) ifcnt++;
if (mif.left(5) == "endif") { if (mif.left(5) == PIStringAscii("endif")) {
if (ifcnt > 0) ifcnt--; if (ifcnt > 0) ifcnt--;
else { else {
//piCout << "main endif" << skip << grab; //piCout << "main endif" << skip << grab;
@@ -912,7 +938,7 @@ PIString PICodeParser::procMacros(PIString fc) {
continue; continue;
} }
} }
if (mif.left(4) == "elif" && ifcnt == 0) { if (mif.left(4) == PIStringAscii("elif") && ifcnt == 0) {
//piCout << "main elif" << skip << grab << cond_ok; //piCout << "main elif" << skip << grab << cond_ok;
if (cond_ok) { if (cond_ok) {
if (grab) { if (grab) {
@@ -930,17 +956,17 @@ PIString PICodeParser::procMacros(PIString fc) {
} }
continue; continue;
} }
if (mif.left(4) == "else" && ifcnt == 0) { if (mif.left(4) == PIStringAscii("else") && ifcnt == 0) {
//piCout << "main else" << skip << grab; //piCout << "main else" << skip << grab;
if (grab) pfc << procMacros(nfc); if (grab) pfc << procMacros(nfc);
if (skip && !cond_ok) {skip = false; grab = true;} if (skip && !cond_ok) {skip = false; grab = true;}
else {skip = true; grab = false;} else {skip = true; grab = false;}
continue; continue;
} }
if (grab) nfc << line << "\n"; if (grab) nfc << line << '\n';
continue; continue;
} }
if (mif.left(2) == "if") { if (mif.left(2) == PIStringAscii("if")) {
//piCout << "main if"; //piCout << "main if";
skip = grab = cond_ok = false; skip = grab = cond_ok = false;
if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true; if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true;
@@ -948,12 +974,12 @@ PIString PICodeParser::procMacros(PIString fc) {
ifcnt = 0; ifcnt = 0;
nfc.clear(); nfc.clear();
} else { } else {
/*if (!*/parseDirective(line.cutLeft(1).trim())/*)*/ parseDirective(line.cutLeft(1).trim());
;//return false; /// WARNING: now skip errors //return false; /// WARNING: now skip errors
} }
} else { } else {
if (grab) nfc << line << "\n"; if (grab) nfc << line << '\n';
else if (!skip) pfc << line << "\n"; else if (!skip) pfc << line << '\n';
} }
} }
return pfc; return pfc;
@@ -964,31 +990,30 @@ bool PICodeParser::parseDirective(PIString d) {
if (d.isEmpty()) return true; if (d.isEmpty()) return true;
PIString dname = d.takeCWord(); PIString dname = d.takeCWord();
//piCout << "parseDirective" << d; //piCout << "parseDirective" << d;
if (dname == "include") { if (dname == PIStringAscii("include")) {
d.replaceAll("<", "\"").replaceAll(">", "\""); d.replaceAll('<', '\"').replaceAll('>', '\"');
PIString cf = cur_file, ifc = d.takeRange("\"", "\""); PIString cf = cur_file, ifc = d.takeRange('\"', '\"');
if (with_includes) { if (with_includes) {
bool ret = parseFileInternal(ifc, with_includes); bool ret = parseFileInternal(ifc, with_includes);
cur_file = cf; cur_file = cf;
return ret; return ret;
} }
} }
if (dname == "define") { if (dname == PIStringAscii("define")) {
PIString mname = d.takeCWord(); PIString mname = d.takeCWord();
//piCout << mname; //piCout << mname;
if (mname == "PIMETA") return true; if (mname == PIStringAscii("PIMETA")) return true;
if (d.left(1) == "(") { // macro if (d.left(1) == PIChar('(')) { // macro
PIStringList args = d.takeRange("(", ")").split(",").trim(); PIStringList args = d.takeRange('(', ')').split(',').trim();
macros << Macro(mname, d.trim(), args); macros << Macro(mname, d.trim(), args);
} else { // define } else { // define
d.trim(); d.trim();
//if (mname == d) d.clear();
defines << Define(mname, d); defines << Define(mname, d);
evaluator.setVariable(mname, complexd_1); evaluator.setVariable(mname, complexd_1);
} }
return true; return true;
} }
if (dname == "undef") { if (dname == PIStringAscii("undef")) {
PIString mname = d.takeCWord(); PIString mname = d.takeCWord();
for (int i = 0; i < defines.size_s(); ++i) for (int i = 0; i < defines.size_s(); ++i)
if (defines[i].first == mname) {defines.remove(i); --i;} if (defines[i].first == mname) {defines.remove(i); --i;}

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
C++ code parser C++ code parser
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -33,8 +33,8 @@ class PIP_EXPORT PICodeParser {
public: public:
PICodeParser(); PICodeParser();
enum PIP_EXPORT Visibility {Global, Public, Protected, Private}; enum Visibility {Global, Public, Protected, Private};
enum PIP_EXPORT Attribute { enum Attribute {
NoAttributes = 0x0, NoAttributes = 0x0,
Const = 0x01, Const = 0x01,
Static = 0x02, Static = 0x02,
@@ -170,7 +170,6 @@ private:
int macros_iter, anon_num; int macros_iter, anon_num;
bool with_includes; bool with_includes;
PIEvaluator evaluator; PIEvaluator evaluator;
//PIVector<Entity * > tree;
PISet<PIString> proc_files; PISet<PIString> proc_files;
PIString cur_file, main_file; PIString cur_file, main_file;
PIStringList includes; PIStringList includes;

View File

@@ -0,0 +1,33 @@
/*! \file picompress.h
* \brief Compress class using zlib
*/
/*
PIP - Platform Independent Primitives
Compress class using zlib
Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICOMPRESS_H
#define PICOMPRESS_H
#include "pip_compress_export.h"
#include "pibytearray.h"
PIP_COMPRESS_EXPORT PIByteArray piCompress(const PIByteArray & ba, int level = 6);
PIP_COMPRESS_EXPORT PIByteArray piDecompress(const PIByteArray & zba);
#endif // PICOMPRESS_H

View File

@@ -0,0 +1,27 @@
/*
PIP - Platform Independent Primitives
Module includes
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICONSOLEMODULE_H
#define PICONSOLEMODULE_H
#include "pikbdlistener.h"
#include "piscreen.h"
#include "piscreentiles.h"
#endif // PICONSOLEMODULE_H

View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Keyboard grabber for console Keyboard grabber for console
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "piincludes_p.h" #include "piincludes_p.h"
@@ -267,10 +267,8 @@ void PIKbdListener::readKeyboard() {
case MOUSE_EVENT: { case MOUSE_EVENT: {
MOUSE_EVENT_RECORD mer = ir.Event.MouseEvent; MOUSE_EVENT_RECORD mer = ir.Event.MouseEvent;
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi);
//height = PRIVATE->sbi.srWindow.Bottom - ;
me.modifiers = getModifiers(mer.dwControlKeyState); me.modifiers = getModifiers(mer.dwControlKeyState);
MouseButtons mb = getButtons(mer.dwButtonState); MouseButtons mb = getButtons(mer.dwButtonState);
//me.action = getButtons(mer.dwButtonState);
if (mer.dwEventFlags & MOUSE_WHEELED) { if (mer.dwEventFlags & MOUSE_WHEELED) {
memcpy((void*)(&we), (const void*)(&me), sizeof(me)); memcpy((void*)(&we), (const void*)(&me), sizeof(me));
we.action = MouseWheel; we.action = MouseWheel;
@@ -317,16 +315,6 @@ void PIKbdListener::readKeyboard() {
piMSleep(10); piMSleep(10);
return; return;
} }
/*if (lc == 0) {
ReadConsole(hIn, &rc, 1, &(PRIVATE->ret), 0);
//cout << "read console" << endl;
lc = char(rc);
}*/
/*if (PRIVATE->ret < 0 || PRIVATE->ret > 3) return;
lc = char(((uchar * )&rc)[PRIVATE->ret - 1]);
for (int i = 0; i < PRIVATE->ret; ++i)
cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
cout << endl << std::hex << rc << endl;*/
#else #else
tcsetattr(0, TCSANOW, &PRIVATE->tterm); tcsetattr(0, TCSANOW, &PRIVATE->tterm);
PRIVATE->ret = read(0, rc, 8); PRIVATE->ret = read(0, rc, 8);

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Keyboard grabber for console Keyboard grabber for console
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -77,7 +77,7 @@ public:
typedef PIFlags<KeyModifier> KeyModifiers; typedef PIFlags<KeyModifier> KeyModifiers;
//! This struct contains information about pressed keyboard key //! This struct contains information about pressed keyboard key
struct KeyEvent { struct PIP_EXPORT KeyEvent {
KeyEvent(int k = 0, KeyModifiers m = 0) {key = k; modifiers = m;} KeyEvent(int k = 0, KeyModifiers m = 0) {key = k; modifiers = m;}
//! Pressed key. It can be simple \b char or special key (see PIKbdListener::SpecialKey) //! Pressed key. It can be simple \b char or special key (see PIKbdListener::SpecialKey)
@@ -106,7 +106,7 @@ public:
typedef PIFlags<MouseButton> MouseButtons; typedef PIFlags<MouseButton> MouseButtons;
//! This struct contains information about mouse action //! This struct contains information about mouse action
struct MouseEvent { struct PIP_EXPORT MouseEvent {
MouseEvent(MouseAction a = MouseButtonPress, MouseButtons b = 0, KeyModifiers m = 0) {x = y = 0; action = a; buttons = b; modifiers = m;} MouseEvent(MouseAction a = MouseButtonPress, MouseButtons b = 0, KeyModifiers m = 0) {x = y = 0; action = a; buttons = b; modifiers = m;}
//! Event X coordinate in view-space, from 0 //! Event X coordinate in view-space, from 0
@@ -126,18 +126,14 @@ public:
}; };
//! This struct contains information about mouse wheel action //! This struct contains information about mouse wheel action
struct WheelEvent: public MouseEvent { struct PIP_EXPORT WheelEvent: public MouseEvent {
WheelEvent(): MouseEvent() {direction = false;} WheelEvent(): MouseEvent() {direction = false;}
//! Wheel direction, /b true - up, /b fasle - down //! Wheel direction, /b true - up, /b fasle - down
bool direction; bool direction;
}; };
#ifdef PIP_CXX11_SUPPORT
typedef std::function<void(KeyEvent, void *)> KBFunc; typedef std::function<void(KeyEvent, void *)> KBFunc;
#else
typedef void (*KBFunc)(KeyEvent, void * );
#endif
//! Constructs keyboard listener with external function "slot" and custom data "data" //! Constructs keyboard listener with external function "slot" and custom data "data"
explicit PIKbdListener(KBFunc slot = 0, void * data = 0, bool startNow = true); explicit PIKbdListener(KBFunc slot = 0, void * data = 0, bool startNow = true);
@@ -154,10 +150,8 @@ public:
//! Set external function to "slot" //! Set external function to "slot"
void setSlot(KBFunc slot) {ret_func = slot;} void setSlot(KBFunc slot) {ret_func = slot;}
#ifdef PIP_CXX11_SUPPORT
//! Set external function to "slot" //! Set external function to "slot"
void setSlot(std::function<void(KeyEvent)> slot) {ret_func = [slot](KeyEvent e, void *){slot(e);};} void setSlot(std::function<void(KeyEvent)> slot) {ret_func = [slot](KeyEvent e, void *){slot(e);};}
#endif
//! Returns if exit key if awaiting //! Returns if exit key if awaiting
bool exitCaptured() const {return exit_enabled;} bool exitCaptured() const {return exit_enabled;}
@@ -213,7 +207,7 @@ private:
void end(); void end();
#ifndef WINDOWS #ifndef WINDOWS
struct EscSeq { struct PIP_EXPORT EscSeq {
const char * seq; const char * seq;
int key; int key;
int mod; int mod;
@@ -234,7 +228,7 @@ private:
static const EscSeq esc_seq[]; static const EscSeq esc_seq[];
#endif #endif
PRIVATE_DECLARATION PRIVATE_DECLARATION(PIP_EXPORT)
KBFunc ret_func; KBFunc ret_func;
int exit_key; int exit_key;
bool exit_enabled, is_active; bool exit_enabled, is_active;

View File

@@ -4,30 +4,31 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Console GUI Console GUI
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PISCREEN_H #ifndef PISCREEN_H
#define PISCREEN_H #define PISCREEN_H
#include "pip_console_export.h"
#include "piscreentile.h" #include "piscreentile.h"
#include "piscreendrawer.h" #include "piscreendrawer.h"
class PIP_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase class PIP_CONSOLE_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase
{ {
PIOBJECT_SUBCLASS(PIScreen, PIThread) PIOBJECT_SUBCLASS(PIScreen, PIThread)
class SystemConsole; class SystemConsole;
@@ -100,7 +101,7 @@ public:
//! \} //! \}
private: private:
class SystemConsole { class PIP_CONSOLE_EXPORT SystemConsole {
public: public:
SystemConsole(); SystemConsole();
~SystemConsole(); ~SystemConsole();
@@ -124,7 +125,7 @@ private:
#else #else
PIString formatString(const PIScreenTypes::Cell & c); PIString formatString(const PIScreenTypes::Cell & c);
#endif #endif
PRIVATE_DECLARATION PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT)
int width, height, pwidth, pheight; int width, height, pwidth, pheight;
int mouse_x, mouse_y; int mouse_x, mouse_y;
PIVector<PIVector<PIScreenTypes::Cell> > cells, pcells; PIVector<PIVector<PIScreenTypes::Cell> > cells, pcells;

View File

@@ -6,35 +6,36 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Tile for PIScreen with PIConsole API Tile for PIScreen with PIConsole API
Copyright (C) 2020 Andrey Bychkov work.a.b@yandex.ru Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PISCREENCONSOLE_H #ifndef PISCREENCONSOLE_H
#define PISCREENCONSOLE_H #define PISCREENCONSOLE_H
#include "pip_console_export.h"
#include "piscreentiles.h" #include "piscreentiles.h"
/// NOTE: incomplete class /// NOTE: incomplete class
/// TODO: write TileVars /// TODO: write TileVars
class PIP_EXPORT TileVars: public PIScreenTile { class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile {
public: public:
TileVars(const PIString & n = PIString()); TileVars(const PIString & n = PIString());
protected: protected:
struct Variable { struct PIP_CONSOLE_EXPORT Variable {
Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = PIScreenTypes::CellFormat(); ptr = 0;} Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = PIScreenTypes::CellFormat(); ptr = 0;}
bool isEmpty() const {return (ptr == 0);} bool isEmpty() const {return (ptr == 0);}
PIString name; PIString name;
@@ -68,7 +69,7 @@ protected:
class PIP_EXPORT PIScreenConsoleTile : public PIScreenTile class PIP_CONSOLE_EXPORT PIScreenConsoleTile : public PIScreenTile
{ {
public: public:
PIScreenConsoleTile(); PIScreenConsoleTile();

View File

@@ -4,29 +4,30 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Drawer for PIScreen Drawer for PIScreen
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PISCREENDRAWER_H #ifndef PISCREENDRAWER_H
#define PISCREENDRAWER_H #define PISCREENDRAWER_H
#include "pip_console_export.h"
#include "piscreentypes.h" #include "piscreentypes.h"
#include "pistring.h" #include "pistring.h"
class PIP_EXPORT PIScreenDrawer class PIP_CONSOLE_EXPORT PIScreenDrawer
{ {
friend class PIScreen; friend class PIScreen;
PIScreenDrawer(PIVector<PIVector<PIScreenTypes::Cell> > & c); PIScreenDrawer(PIVector<PIVector<PIScreenTypes::Cell> > & c);

View File

@@ -4,31 +4,32 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Basic PIScreen tile Basic PIScreen tile
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PISCREENTILE_H #ifndef PISCREENTILE_H
#define PISCREENTILE_H #define PISCREENTILE_H
#include "pip_console_export.h"
#include "piscreentypes.h" #include "piscreentypes.h"
#include "pikbdlistener.h" #include "pikbdlistener.h"
class PIScreenDrawer; class PIScreenDrawer;
class PIP_EXPORT PIScreenTile: public PIObject { class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
friend class PIScreen; friend class PIScreen;
PIOBJECT_SUBCLASS(PIScreenTile, PIObject) PIOBJECT_SUBCLASS(PIScreenTile, PIObject)
public: public:

View File

@@ -4,29 +4,30 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Various tiles for PIScreen Various tiles for PIScreen
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PISCREENTILES_H #ifndef PISCREENTILES_H
#define PISCREENTILES_H #define PISCREENTILES_H
#include "pip_console_export.h"
#include "piscreentile.h" #include "piscreentile.h"
class PIP_EXPORT TileSimple: public PIScreenTile { class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile {
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile) PIOBJECT_SUBCLASS(TileSimple, PIScreenTile)
public: public:
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row; typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
@@ -43,7 +44,7 @@ protected:
class TileList; class TileList;
class PIP_EXPORT TileScrollBar: public PIScreenTile { class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile {
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile) PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile)
friend class TileList; friend class TileList;
public: public:
@@ -66,7 +67,7 @@ protected:
}; };
class PIP_EXPORT TileList: public PIScreenTile { class PIP_CONSOLE_EXPORT TileList: public PIScreenTile {
PIOBJECT_SUBCLASS(TileList, PIScreenTile) PIOBJECT_SUBCLASS(TileList, PIScreenTile)
public: public:
TileList(const PIString & n = PIString()); TileList(const PIString & n = PIString());
@@ -98,7 +99,7 @@ protected:
}; };
class PIP_EXPORT TileButton: public PIScreenTile { class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile {
PIOBJECT_SUBCLASS(TileButton, PIScreenTile) PIOBJECT_SUBCLASS(TileButton, PIScreenTile)
public: public:
TileButton(const PIString & n = PIString()); TileButton(const PIString & n = PIString());
@@ -118,7 +119,7 @@ protected:
class PIP_EXPORT TileButtons: public PIScreenTile { class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile {
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile) PIOBJECT_SUBCLASS(TileButtons, PIScreenTile)
public: public:
TileButtons(const PIString & n = PIString()); TileButtons(const PIString & n = PIString());
@@ -143,7 +144,7 @@ protected:
}; };
class PIP_EXPORT TileCheck: public PIScreenTile { class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile {
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile) PIOBJECT_SUBCLASS(TileCheck, PIScreenTile)
public: public:
TileCheck(const PIString & n = PIString()); TileCheck(const PIString & n = PIString());
@@ -162,7 +163,7 @@ protected:
}; };
class PIP_EXPORT TileProgress: public PIScreenTile { class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile {
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile) PIOBJECT_SUBCLASS(TileProgress, PIScreenTile)
public: public:
TileProgress(const PIString & n = PIString()); TileProgress(const PIString & n = PIString());
@@ -178,7 +179,7 @@ protected:
}; };
class PIP_EXPORT TilePICout: public TileList { class PIP_CONSOLE_EXPORT TilePICout: public TileList {
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile) PIOBJECT_SUBCLASS(TilePICout, PIScreenTile)
public: public:
TilePICout(const PIString & n = PIString()); TilePICout(const PIString & n = PIString());
@@ -191,14 +192,11 @@ protected:
}; };
class PIP_EXPORT TileInput: public PIScreenTile { class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile {
PIOBJECT_SUBCLASS(TileInput, PIScreenTile) PIOBJECT_SUBCLASS(TileInput, PIScreenTile)
public: public:
TileInput(const PIString & n = PIString()); TileInput(const PIString & n = PIString());
virtual ~TileInput() {} virtual ~TileInput() {}
/*enum EventType {
EditFinished
};*/
PIScreenTypes::CellFormat format; PIScreenTypes::CellFormat format;
PIString text; PIString text;
int max_length; int max_length;
@@ -212,34 +210,5 @@ protected:
PITimeMeasurer tm_blink; PITimeMeasurer tm_blink;
}; };
/*
class PIP_EXPORT TileTabs: public PIScreenTile {
PIOBJECT_SUBCLASS(TileTabs, PIScreenTile)
public:
TileTabs(const PIString & n = PIString());
enum EventType {
TabChanged
};
struct Tab {
Tab(const PIString & l = PIString(), int k = 0, PIScreenTile * t = 0) {
label = l;
key = k;
tile = t;
}
PIString label;
int key;
PIScreenTile * tile;
};
PIScreenTypes::CellFormat format_tab;
PIScreenTypes::CellFormat format_tab_selected;
PIDeque<Tab> tabs;
protected:
void sizeHint(int & w, int & h) const;
void drawEvent(PIScreenDrawer * d);
bool keyEvent(PIKbdListener::KeyEvent key);
void selectTab(int index);
int cur;
};
*/
#endif // PISCREENTILES_H #endif // PISCREENTILES_H

View File

@@ -4,25 +4,26 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Types for PIScreen Types for PIScreen
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PISCREENTYPES_H #ifndef PISCREENTYPES_H
#define PISCREENTYPES_H #define PISCREENTYPES_H
#include "pip_console_export.h"
#include "pivariant.h" #include "pivariant.h"
class PIScreenTile; class PIScreenTile;
@@ -30,7 +31,7 @@ class PIScreenTile;
namespace PIScreenTypes { namespace PIScreenTypes {
//! Color for chars or background //! Color for chars or background
enum PIP_EXPORT Color { enum Color {
Default /** Default */, Default /** Default */,
Black /** Black */, Black /** Black */,
Red /** Red */, Red /** Red */,
@@ -44,7 +45,7 @@ namespace PIScreenTypes {
}; };
//! Flags for chars //! Flags for chars
enum PIP_EXPORT CharFlag { enum CharFlag {
Bold /** Bold or bright */ = 0x1, Bold /** Bold or bright */ = 0x1,
Blink /** Blink text */ = 0x2, Blink /** Blink text */ = 0x2,
Underline /** Underline text */ = 0x4, Underline /** Underline text */ = 0x4,
@@ -52,14 +53,14 @@ namespace PIScreenTypes {
}; };
//! Alignment //! Alignment
enum PIP_EXPORT Alignment { enum Alignment {
Left /** Left */ , Left /** Left */ ,
Center /** Center */ , Center /** Center */ ,
Right /** Right */ Right /** Right */
}; };
//! Size policy //! Size policy
enum PIP_EXPORT SizePolicy { enum SizePolicy {
Fixed /** Fixed size */ , Fixed /** Fixed size */ ,
Preferred /** Preferred size */ , Preferred /** Preferred size */ ,
Expanding /** Maximum available size */ , Expanding /** Maximum available size */ ,
@@ -67,21 +68,13 @@ namespace PIScreenTypes {
}; };
//! Direction //! Direction
enum PIP_EXPORT Direction { enum Direction {
Horizontal /** Horizontal */ , Horizontal /** Horizontal */ ,
Vertical /** Vertical */ Vertical /** Vertical */
}; };
//! Position
enum PIP_EXPORT Position {
//Left /** Left */ ,
//Right /** Right */ ,
//Top /** Top */ ,
//Bottom /** Bottom */
};
//! Focus flags //! Focus flags
enum PIP_EXPORT FocusFlag { enum FocusFlag {
CanHasFocus /** Tile can has focus */ = 0x1, CanHasFocus /** Tile can has focus */ = 0x1,
NextByTab /** Focus passed to next tile by tab key */ = 0x2, NextByTab /** Focus passed to next tile by tab key */ = 0x2,
NextByArrowsHorizontal /** Focus passed to next tile by arrow keys left or right */ = 0x4, NextByArrowsHorizontal /** Focus passed to next tile by arrow keys left or right */ = 0x4,
@@ -95,7 +88,7 @@ namespace PIScreenTypes {
typedef PIFlags<CharFlag> CharFlags; typedef PIFlags<CharFlag> CharFlags;
typedef PIFlags<FocusFlag> FocusFlags; typedef PIFlags<FocusFlag> FocusFlags;
union PIP_EXPORT CellFormat { union PIP_CONSOLE_EXPORT CellFormat {
CellFormat(ushort f = 0) {raw_format = f;} CellFormat(ushort f = 0) {raw_format = f;}
CellFormat(Color col_char, Color col_back = Default, CharFlags flags_ = 0) { CellFormat(Color col_char, Color col_back = Default, CharFlags flags_ = 0) {
color_char = col_char; color_char = col_char;
@@ -112,7 +105,7 @@ namespace PIScreenTypes {
bool operator !=(const CellFormat & c) const {return raw_format != c.raw_format;} bool operator !=(const CellFormat & c) const {return raw_format != c.raw_format;}
}; };
struct PIP_EXPORT Cell { struct PIP_CONSOLE_EXPORT Cell {
Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {symbol = c; format = f;} Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {symbol = c; format = f;}
CellFormat format; CellFormat format;
PIChar symbol; PIChar symbol;
@@ -128,13 +121,13 @@ namespace PIScreenTypes {
} }
}; };
struct PIP_EXPORT TileEvent { struct PIP_CONSOLE_EXPORT TileEvent {
TileEvent(int t = -1, const PIVariant & d = PIVariant()): type(t), data(d) {} TileEvent(int t = -1, const PIVariant & d = PIVariant()): type(t), data(d) {}
int type; int type;
PIVariant data; PIVariant data;
}; };
class PIScreenBase { class PIP_CONSOLE_EXPORT PIScreenBase {
public: public:
PIScreenBase() {} PIScreenBase() {}
virtual ~PIScreenBase() {} virtual ~PIScreenBase() {}
@@ -150,8 +143,5 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIScreenTypes::Cell & v)
inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;} inline PIByteArray & operator >>(PIByteArray & s, PIScreenTypes::Cell & v) {s >> v.format.raw_format >> v.symbol; return s;}
//__PICONTAINERS_SIMPLE_TYPE__(PIScreenTypes::Cell)
//__PIBYTEARRAY_SIMPLE_TYPE__(PIScreenTypes::Cell)
#endif // PISCREENTYPES_H #endif // PISCREENTYPES_H

View File

@@ -4,30 +4,31 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Virtual terminal Virtual terminal
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PITERMINAL_H #ifndef PITERMINAL_H
#define PITERMINAL_H #define PITERMINAL_H
#include "pip_console_export.h"
#include "pikbdlistener.h" #include "pikbdlistener.h"
#include "piscreentypes.h" #include "piscreentypes.h"
class PIP_EXPORT PITerminal: public PIThread class PIP_CONSOLE_EXPORT PITerminal: public PIThread
{ {
PIOBJECT_SUBCLASS(PITerminal, PIThread) PIOBJECT_SUBCLASS(PITerminal, PIThread)
public: public:
@@ -63,7 +64,7 @@ private:
int termType(const PIString & t); int termType(const PIString & t);
#endif #endif
PRIVATE_DECLARATION PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT)
int dsize_x, dsize_y; int dsize_x, dsize_y;
int size_x, size_y, cursor_x, cursor_y; int size_x, size_y, cursor_x, cursor_y;
bool cursor_blink, cursor_visible; bool cursor_blink, cursor_visible;

View File

@@ -0,0 +1,374 @@
/*
PIP - Platform Independent Primitives
Generic containers
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/** \class PIVector
* \brief Dynamic array of any type
* \details This class used to store dynamic array of any
* type of data. In memory data stored linear. You can insert
* item in any place of remove some items from any place.
* For quick add elements this is stream operator <<.
* \fn PIVector::PIVector();
* Contructs an empty vector
* \fn PIVector::PIVector(size_t size, const T & value = T());
* \brief Contructs vector with size "size" filled elements "value"
* \details Example: \snippet picontainers.cpp PIVector::PIVector
* \fn const T & PIVector::at(size_t index) const;
* \brief Read-only access to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::at_c
* \sa \a operator[]
* \fn T & PIVector::at(size_t index);
* \brief Full access to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::at
* \sa \a operator[]
* \fn const T * PIVector::data(size_t index = 0) const;
* \brief Read-only pointer to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::data_c
* \fn T * PIVector::data(size_t index = 0);
* \brief Pointer to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::data
* \fn size_t PIVector::size() const;
* \brief Elements count
* \fn ssize_t PIVector::size_s() const;
* \brief Elements count
* \fn bool PIVector::isEmpty() const;
* \brief Return \c "true" if vector is empty, i.e. size = 0
* \fn bool PIVector::has(const T & t) const;
* \fn bool PIVector::contains(const T & v) const;
* \brief Return \c "true" if vector has at least one element equal "t"
* \fn int PIVector::etries(const T & t) const;
* \brief Return how many times element "t" appears in vector
* \fn ssize_t PIVector::indexOf(const T & t) const;
* \brief Return index of first element equal "t" or -1 if there is no such element
* \fn ssize_t PIVector::lastIndexOf(const T & t) const;
* \brief Return index of last element equal "t" or -1 if there is no such element
* \fn static int PIVector::compare_func(const T * t0, const T * t1);
* \brief Standard compare function for type "T". Return 0 if t0 = t1, -1 if t0 < t1 and 1 if t0 > t1.
* \fn void PIVector::resize(size_t size, const T & new_type = T());
* \brief Resize vector to size "size"
* \details Elements removed from end of vector if new size < old size, or added new elements = "new_type" if new size > old size.\n
* Example: \snippet picontainers.cpp PIVector::resize
* \sa \a size(), \a clear()
* \fn PIVector & PIVector::enlarge(size_t size);
* \brief Increase vector size with "size" elements
* \fn void PIVector::clear();
* \brief Clear vector. Equivalent to call <tt>"resize(0)"</tt>
* \fn PIVector & PIVector::sort(CompareFunc compare = compare_func);
* \brief Sort vector using quick sort algorithm and standard compare function
* \details Example: \snippet picontainers.cpp PIVector::sort_0
* With custom compare function: \snippet picontainers.cpp PIVector::sort_1
* \fn PIVector & PIVector::fill(const T & t);
* \brief Fill vector with elements "t" leave size is unchanged and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::fill
* \fn PIVector & PIVector::assign(const T & t = T());
* \brief Synonym of \a fill(t)
* \fn PIVector & PIVector::assign(size_t new_size, const T & t);
* \brief Resize to "new_size", then fill with "t"
* \fn T & PIVector::back();
* \brief Last element of the vector
* \fn const T & PIVector::back() const;
* \brief Last element of the vector
* \fn T & PIVector::front();
* \brief First element of the vector
* \fn const T & PIVector::front() const;
* \brief First element of the vector
* \fn PIVector & PIVector::push_back(const T & t);
* \brief Add new element "t" at the end of vector and return reference to vector
* \fn PIVector & PIVector::push_front(const T & t);
* \brief Add new element "t" at the beginning of vector and return reference to vector
* \fn PIVector & PIVector::pop_back();
* \brief Remove one element from the end of vector and return reference to vector
* \fn PIVector & PIVector::pop_front();
* \brief Remove one element from the beginning of vector and return reference to vector
* \fn T PIVector::take_back();
* \brief Remove one element from the end of vector and return it
* \fn T PIVector::take_front();
* \brief Remove one element from the beginning of vector and return it
* \fn PIVector & PIVector::remove(size_t index);
* \brief Remove one element by index "index" and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::remove_0
* \sa \a removeOne(), \a removeAll()
* \fn PIVector & PIVector::remove(size_t index, size_t count);
* \brief Remove "count" elements by first index "index" and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::remove_1
* \sa \a removeOne(), \a removeAll()
* \fn PIVector & PIVector::removeOne(const T & v);
* \brief Remove no more than one element equal "v" and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::removeOne
* \sa \a remove(), \a removeAll()
* \fn PIVector & PIVector::removeAll(const T & v);
* \brief Remove all elements equal "v" and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::removeAll
* \sa \a remove(), \a removeOne()
* \fn PIVector & PIVector::insert(size_t pos, const T & t);
* \brief Insert element "t" after index "pos" and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::insert_0
* \fn PIVector & PIVector::insert(size_t pos, const PIVector & t);
* \brief Insert other vector "t" after index "pos" and return reference to vector
* \details Example: \snippet picontainers.cpp PIVector::insert_1
* \fn T & PIVector::operator [](size_t index);
* \brief Full access to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::()
* \sa \a at()
* \fn const T & PIVector::operator [](size_t index) const;
* \brief Read-only access to element by index "index"
* \details Example: \snippet picontainers.cpp PIVector::()_c
* \sa \a at()
* \fn PIVector & PIVector::operator <<(const T & t);
* \brief Add new element "t" at the end of vector and return reference to vector
* \fn PIVector & PIVector::operator <<(const PIVector & t);
* \brief Add vector "t" at the end of vector and return reference to vector
* \fn bool PIVector::operator ==(const PIVector & t);
* \brief Compare with vector "t"
* \fn bool PIVector::operator !=(const PIVector & t);
* \brief Compare with vector "t"
* */
/** \class PIMap
* \brief Associative array
* \details This class used to store Key = Value array of any
* type of data. \a value() returns value for key and leave map
* unchaged in any case. \a operator [] create entry in map if
* there is no entry for given key. You can retrieve all
* keys by method \a keys() and all values by methos \a values().
* To iterate all entries use class PIMapIterator, or methods
* \a makeIterator() and \a makeReverseIterator().
* \fn PIMap::PIMap();
* \brief Contructs an empty map
* \fn PIMap::PIMap(const PIMap & other);
* \brief Contructs a copy of "other"
* \fn PIMap & PIMap::operator =(const PIMap & other);
* \brief Copy operator
* \fn PIMap::PIMap(const PIMap & other);
* \brief Contructs a copy of "other"
* \fn PIMapIterator PIMap::makeIterator() const
* \brief Returns PIMapIterator for this map
* \fn PIMapIterator PIMap::makeReverseIterator() const
* \brief Returns reverse PIMapIterator for this map
* \fn size_t PIMap::size() const
* \brief Returns entries count
* \fn int PIMap::size_s() const
* \brief Returns entries count
* \fn size_t PIMap::length() const
* \brief Returns entries count
* \fn bool PIMap::isEmpty() const
* \brief Returns if map is empty
* \fn T & PIMap::operator [](const Key & key)
* \brief Returns value for key "key". If there is no key in map, create one.
* \fn const T PIMap::operator [](const Key & key) const
* \brief Returns value for key "key". If there is no key in map, returns default T().
* \fn T & PIMap::at(const Key & key)
* \brief Equivalent to operator []
* \fn const T PIMap::at(const Key & key) const
* \brief Equivalent to operator []
* \fn PIMap & PIMap::operator <<(const PIMap & other)
* \brief Insert all etries of "other" to this map. Override existing values.
* \fn bool PIMap::operator ==(const PIMap & t) const
* \brief Compare operator
* \fn bool PIMap::operator !=(const PIMap & t) const
* \brief Compare operator
* \fn bool PIMap::contains(const Key & key) const
* \brief Returns "true" if map contains entry with key "key"
* \fn PIMap & PIMap::reserve(size_t new_size)
* \brief Reserve space for "new_size" entries
* \fn PIMap & PIMap::removeOne(const Key & key)
* \brief Remove entry with key "key"
* \fn PIMap & PIMap::remove(const Key & key)
* \brief Equivalent \a removeOne(key)
* \fn PIMap & PIMap::erase(const Key & key)
* \brief Equivalent \a removeOne(key)
* \fn PIMap & PIMap::clear()
* \brief Clear map
* \fn void PIMap::swap(PIMap & other)
* \brief Swap map with "other"
* \fn PIMap & PIMap::insert(const Key & key, const T & value)
* \brief Insert or rewrite entry with key "key" and value "value"
* \fn const T PIMap::value(const Key & key, const T & default = T())
* \brief Returns value for key "key". If there is no key in map, returns "default".
* \fn PIVector<T> PIMap::values() const
* \brief Returns all values as PIVector
* \fn Key PIMap::key(const T & value, const Key & default = Key()) const
* \brief Returns key for first founded value "value". If there is no such value in map, returns "default".
* \fn PIVector<Key> PIMap::keys() const
* \brief Returns all keys as PIVector
* */
/** \class PIMapIterator
* \brief Helper class to iterate over PIMap
* \details This class used to access keys and values in PIMap.
* You can use constructor to create iterator, or use \a PIMap::makeIterator()
* and \a PIMap::makeReverseIterator() methods.
*
* First usage variant:
* \code
* PIMap<int, PIString> m;
* m[1] = "one";
* m[2] = "two";
* m[4] = "four";
*
* auto it = m.makeIterator();
* while (it.next()) {
* piCout << it.key() << it.value();
* }
* // 1 one
* // 2 two
* // 4 four
* \endcode
*
* Using hasNext():
* \code
* while (it.hasNext()) {
* it.next();
* \endcode
*
* Using constructor:
* \code
* PIMapIterator<int, PIString> it(m);
* \endcode
*
* Write access:
* \code
* while (it.next()) {
* it.valueRef().append("_!");
* piCout << it.key() << it.value();
* }
*
* // 1 one_!
* // 2 two_!
* // 4 four_!
* \endcode
*
* Reverse iterator:
* \code
* auto it = m.makeReverseIterator();
* while (it.next()) {
* piCout << it.key() << it.value();
* }
*
* // 4 four
* // 2 two
* // 1 one
* \endcode
* \fn PIMapIterator(const PIMap & map, bool reverse = false)
* \brief Contructs iterator for "map". Current position is invalid.
* \fn const Key & PIMapIterator::key() const
* \brief Returns current entry key
* \fn const T & PIMapIterator::value() const
* \brief Returns current entry value
* \fn T & PIMapIterator::valueRef() const
* \brief Returns reference to current entry value
* \fn bool PIMapIterator::hasNext()
* \brief Returns if iterator can jump to next entry
* \fn bool PIMapIterator::next()
* \brief Jump to next entry and return if new position is valid.
* */

View File

@@ -0,0 +1,130 @@
/*! \file picontainers.h
* \brief Base for generic containers
*
* This file declare all containers and useful macros
* to use them
*/
/*
PIP - Platform Independent Primitives
Base for generic containers
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICONTAINERS_H
#define PICONTAINERS_H
#include "picout.h"
#include "piintrospection_containers.h"
#ifdef PIP_DEBUG
# ifdef NDEBUG
# undef NDEBUG
# endif
# include <cassert>
#endif
#ifndef assert
# define assert(x)
#endif
#ifdef MAC_OS
# include <stdlib.h>
#else
# include <malloc.h>
#endif
#include <string.h>
#include <new>
#ifndef PIP_MEMALIGN_BYTES
# define PIP_MEMALIGN_BYTES (sizeof(void*)*4)
#endif
#ifdef WINDOWS
# ifdef CC_GCC
# define amalloc(s) __mingw_aligned_malloc(s, PIP_MEMALIGN_BYTES)
# define afree(p) __mingw_aligned_free(p)
# else
# ifdef CC_VC
# define amalloc(s) _aligned_malloc(s, PIP_MEMALIGN_BYTES)
# define afree(p) _aligned_free(p)
# endif
# endif
#else
# define amalloc(s) aligned_alloc(PIP_MEMALIGN_BYTES, s)
# define afree(p) free(p)
#endif
#ifdef DOXYGEN
/*!\brief Macro for iterate any container
* \details Use this macros instead of standard "for"
* to get read/write access to each element of container.
* Pass direction is direct \n
* Example: \snippet picontainers.cpp foreach
*/
# define piForeach(i,c)
/*!\brief Macro for iterate any container only for read
* \details Use this macros instead of standard "for"
* to get read access to each element of container.
* Pass direction is direct \n
* Example: \snippet picontainers.cpp foreachC
*/
# define piForeachC(i,c)
/*!\brief Macro for iterate any container with reverse direction
* \details Use this macros instead of standard "for"
* to get read/write access to each element of container.
* Pass direction is reverse \n
* Example: \snippet picontainers.cpp foreachR
*/
# define piForeachR(i,c)
/*!\brief Macro for iterate any container only for read with reverse direction
* \details Use this macros instead of standard "for"
* to get read access to each element of container.
* Pass direction is reverse \n
* Example: \snippet picontainers.cpp foreachCR
*/
# define piForeachCR(i,c)
#else
template <typename C>
struct _reverse_wrapper {
C & c_;
_reverse_wrapper(C & c): c_(c) {}
_reverse_wrapper(const C & c): c_(const_cast<C&>(c)) {}
typename C::reverse_iterator begin() {return c_.rbegin();}
typename C::reverse_iterator end() {return c_.rend(); }
typename C::const_reverse_iterator begin() const {return c_.rbegin();}
typename C::const_reverse_iterator end() const {return c_.rend(); }
};
template <typename C> _reverse_wrapper<C> _reverse_wrap(C & c) {return _reverse_wrapper<C>(c);}
template <typename C> _reverse_wrapper<C> _reverse_wrap(const C & c) {return _reverse_wrapper<C>(c);}
# define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c)
# define piForeach(i,c) for(i : c)
# define piForeachC(i,c) for(const i : c)
# define piForeachR(i,c) for(i : _reverse_wrap(c))
# define piForeachRC(i,c) for(const i : _reverse_wrap(c))
# define piForeachCR piForeachRC
#endif // DOXYGEN
#endif // PICONTAINERS_H

View File

@@ -0,0 +1,31 @@
/*
PIP - Platform Independent Primitives
Module includes
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PICONTAINERSMODULE_H
#define PICONTAINERSMODULE_H
#include "pivector.h"
#include "pideque.h"
#include "pimap.h"
#include "piqueue.h"
#include "piset.h"
#include "pistack.h"
#include "pivector2d.h"
#endif // PICONTAINERSMODULE_H

View File

@@ -6,19 +6,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Dynamic array of any type Dynamic array of any type
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -28,14 +28,10 @@
#include "picontainers.h" #include "picontainers.h"
#if !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
template <typename T> template <typename T>
class PIDeque { class PIDeque {
public: public:
inline PIDeque(): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { inline PIDeque(): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
//piCout << "PIDeque";
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
} }
inline PIDeque(const PIDeque<T> & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { inline PIDeque(const PIDeque<T> & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
@@ -52,8 +48,10 @@ public:
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(pid_size, f); resize(pid_size, f);
} }
inline PIDeque(PIDeque<T> && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) {
other._reset();
}
inline virtual ~PIDeque() { inline virtual ~PIDeque() {
//piCout << "~PIDeque";
PIINTROSPECTION_CONTAINER_DELETE(T) PIINTROSPECTION_CONTAINER_DELETE(T)
PIINTROSPECTION_CONTAINER_FREE(T, (pid_rsize)) PIINTROSPECTION_CONTAINER_FREE(T, (pid_rsize))
deleteT(pid_data + pid_start, pid_size); deleteT(pid_data + pid_start, pid_size);
@@ -69,6 +67,11 @@ public:
return *this; return *this;
} }
inline PIDeque<T> & operator =(PIDeque<T> && other) {
swap(other);
return *this;
}
typedef T value_type; typedef T value_type;
class iterator { class iterator {
@@ -97,7 +100,6 @@ public:
size_t pos; size_t pos;
public: public:
inline const_iterator(): parent(0), pos(0) {} inline const_iterator(): parent(0), pos(0) {}
//inline T & operator *() {return (*parent)[pos];}
inline const T & operator *() const {return (*parent)[pos];} inline const T & operator *() const {return (*parent)[pos];}
inline void operator ++() {++pos;} inline void operator ++() {++pos;}
inline void operator ++(int) {++pos;} inline void operator ++(int) {++pos;}
@@ -133,7 +135,6 @@ public:
size_t pos; size_t pos;
public: public:
inline const_reverse_iterator(): parent(0), pos(0) {} inline const_reverse_iterator(): parent(0), pos(0) {}
//inline T & operator *() {return (*parent)[pos];}
inline const T & operator *() const {return (*parent)[pos];} inline const T & operator *() const {return (*parent)[pos];}
inline void operator ++() {--pos;} inline void operator ++() {--pos;}
inline void operator ++(int) {--pos;} inline void operator ++(int) {--pos;}
@@ -261,6 +262,23 @@ public:
elementNew(pid_data + pid_start + index, v); elementNew(pid_data + pid_start + index, v);
return *this; return *this;
} }
inline PIDeque<T> & insert(size_t index, T && v) {
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
if (dir) {
alloc(pid_size + 1, true);
if (index < pid_size - 1) {
size_t os = pid_size - index - 1;
memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
}
} else {
alloc(pid_size + 1, false, -1);
if (index > 0)
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
}
PIINTROSPECTION_CONTAINER_USED(T, 1)
elementNew(pid_data + pid_start + index, std::move(v));
return *this;
}
inline PIDeque<T> & insert(size_t index, const PIDeque<T> & other) { inline PIDeque<T> & insert(size_t index, const PIDeque<T> & other) {
if (other.isEmpty()) return *this; if (other.isEmpty()) return *this;
assert(&other != this); assert(&other != this);
@@ -341,7 +359,14 @@ public:
elementNew(pid_data + pid_start + pid_size - 1, v); elementNew(pid_data + pid_start + pid_size - 1, v);
return *this; return *this;
} }
inline PIDeque<T> & push_back(T && v) {
alloc(pid_size + 1, true);
PIINTROSPECTION_CONTAINER_USED(T, 1);
elementNew(pid_data + pid_start + pid_size - 1, std::move(v));
return *this;
}
inline PIDeque<T> & append(const T & v) {return push_back(v);} inline PIDeque<T> & append(const T & v) {return push_back(v);}
inline PIDeque<T> & append(T && v) {return push_back(std::move(v));}
inline PIDeque<T> & append(const PIDeque<T> & t) { inline PIDeque<T> & append(const PIDeque<T> & t) {
assert(&t != this); assert(&t != this);
size_t ps = pid_size; size_t ps = pid_size;
@@ -350,10 +375,13 @@ public:
return *this; return *this;
} }
inline PIDeque<T> & operator <<(const T & v) {return push_back(v);} inline PIDeque<T> & operator <<(const T & v) {return push_back(v);}
inline PIDeque<T> & operator <<(T && v) {return push_back(std::move(v));}
inline PIDeque<T> & operator <<(const PIDeque<T> & t) {return append(t);} inline PIDeque<T> & operator <<(const PIDeque<T> & t) {return append(t);}
inline PIDeque<T> & push_front(const T & v) {insert(0, v); return *this;} inline PIDeque<T> & push_front(const T & v) {insert(0, v); return *this;}
inline PIDeque<T> & push_front(T && v) {insert(0, std::move(v)); return *this;}
inline PIDeque<T> & prepend(const T & v) {return push_front(v);} inline PIDeque<T> & prepend(const T & v) {return push_front(v);}
inline PIDeque<T> & prepend(T && v) {return push_front(std::move(v));}
inline PIDeque<T> & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;} inline PIDeque<T> & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;}
inline PIDeque<T> & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;} inline PIDeque<T> & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;}
@@ -369,7 +397,6 @@ public:
return ret; return ret;
} }
#ifdef PIP_CXX11_SUPPORT
const PIDeque<T> & forEach(std::function<void(const T &)> f) const { const PIDeque<T> & forEach(std::function<void(const T &)> f) const {
for (uint i = 0; i < pid_size; ++i) for (uint i = 0; i < pid_size; ++i)
f(pid_data[i + pid_start]); f(pid_data[i + pid_start]);
@@ -393,7 +420,6 @@ public:
ret << f(pid_data[i + pid_start]); ret << f(pid_data[i + pid_start]);
return ret; return ret;
} }
#endif
private: private:
inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;} inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;}
@@ -419,6 +445,7 @@ private:
} }
} }
inline void elementNew(T * to, const T & from) {new(to)T(from);} inline void elementNew(T * to, const T & from) {new(to)T(from);}
inline void elementNew(T * to, T && from) {new(to)T(std::move(from));}
inline void elementDelete(T & from) {from.~T();} inline void elementDelete(T & from) {from.~T();}
inline void dealloc() { inline void dealloc() {
if ((uchar*)pid_data != 0) free((uchar*)pid_data); if ((uchar*)pid_data != 0) free((uchar*)pid_data);
@@ -492,6 +519,7 @@ private:
template<> inline void PIDeque<T>::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIDeque<T>::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \
template<> inline void PIDeque<T>::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIDeque<T>::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \
template<> inline void PIDeque<T>::elementNew(T * to, const T & from) {(*to) = from;} \ template<> inline void PIDeque<T>::elementNew(T * to, const T & from) {(*to) = from;} \
template<> inline void PIDeque<T>::elementNew(T * to, T && from) {(*to) = std::move(from);} \
template<> inline void PIDeque<T>::elementDelete(T &) {;} \ template<> inline void PIDeque<T>::elementDelete(T &) {;} \
template<> inline PIDeque<T> & PIDeque<T>::_resizeRaw(size_t new_size) { \ template<> inline PIDeque<T> & PIDeque<T>::_resizeRaw(size_t new_size) { \
if (new_size > pid_size) { \ if (new_size > pid_size) { \
@@ -507,33 +535,6 @@ private:
template<> inline PIDeque<T> & PIDeque<T>::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);} template<> inline PIDeque<T> & PIDeque<T>::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);}
#else
template<typename Type, typename Allocator = std::allocator<Type> >
class PIP_EXPORT PIDeque: public deque<Type, Allocator> {
typedef PIDeque<Type, Allocator> _CDeque;
typedef deque<Type, Allocator> _stlc;
public:
PIDeque() {piMonitor.containers++;}
PIDeque(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);}
PIDeque(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);}
PIDeque(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);}
PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);}
~PIDeque() {piMonitor.containers--;}
int size_s() const {return static_cast<int>(_stlc::size());}
bool isEmpty() const {return _stlc::empty();}
bool has(const Type & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
int etries(const Type & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
_CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;}
PIDeque<Type> toVector() {PIDeque<Type> v; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) v << *i; return v;}
};
#define __PIDEQUE_SIMPLE_FUNCTIONS__(T)
#endif
__PIDEQUE_SIMPLE_TYPE__(bool) __PIDEQUE_SIMPLE_TYPE__(bool)
__PIDEQUE_SIMPLE_TYPE__(char) __PIDEQUE_SIMPLE_TYPE__(char)
__PIDEQUE_SIMPLE_TYPE__(uchar) __PIDEQUE_SIMPLE_TYPE__(uchar)
@@ -570,5 +571,7 @@ inline PICout operator <<(PICout s, const PIDeque<T> & v) {
return s; return s;
} }
template<typename T> inline void piSwap(PIDeque<T> & f, PIDeque<T> & s) {f.swap(s);}
#endif // PIDEQUE_H #endif // PIDEQUE_H

View File

@@ -6,19 +6,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Associative array with custom types of key and value Associative array with custom types of key and value
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -33,8 +33,6 @@ __PIDEQUE_SIMPLE_TYPE__(T)\
__PIVECTOR_SIMPLE_TYPE__(T) __PIVECTOR_SIMPLE_TYPE__(T)
#if !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
template<class T> template<class T>
void piQuickSort(T * a, ssize_t N) { void piQuickSort(T * a, ssize_t N) {
if (N < 1) return; if (N < 1) return;
@@ -59,7 +57,7 @@ void piQuickSort(T * a, ssize_t N) {
if (i <= j) { if (i <= j) {
if (i != j) { if (i != j) {
//piCout << "swap" << i << j << a[i] << a[j]; //piCout << "swap" << i << j << a[i] << a[j];
piSwapBinary<T>(a[i], a[j]); piSwap<T>(a[i], a[j]);
} }
i++; j--; i++; j--;
} }
@@ -69,13 +67,20 @@ void piQuickSort(T * a, ssize_t N) {
} }
} }
template <typename Key, typename T>
class PIMapIterator;
template <typename Key, typename T> template <typename Key, typename T>
class PIMap { class PIMap {
template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIMap<Key1, T1> & v); template <typename Key1, typename T1> friend PIByteArray & operator >>(PIByteArray & s, PIMap<Key1, T1> & v);
template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIMap<Key1, T1> & v); template <typename Key1, typename T1> friend PIByteArray & operator <<(PIByteArray & s, const PIMap<Key1, T1> & v);
template <typename Key1, typename T1> friend class PIMapIterator;
public: public:
PIMap() {;} PIMap() {;}
PIMap(const PIMap<Key, T> & other) {*this = other;} PIMap(const PIMap<Key, T> & other) {*this = other;}
PIMap(PIMap<Key, T> && other) : pim_content(std::move(other.pim_content)), pim_index(std::move(other.pim_index)) {}
virtual ~PIMap() {;} virtual ~PIMap() {;}
PIMap<Key, T> & operator =(const PIMap<Key, T> & other) { PIMap<Key, T> & operator =(const PIMap<Key, T> & other) {
@@ -86,6 +91,11 @@ public:
return *this; return *this;
} }
PIMap<Key, T> & operator =(PIMap<Key, T> && other) {
swap(other);
return *this;
}
typedef T mapped_type; typedef T mapped_type;
typedef Key key_type; typedef Key key_type;
typedef PIPair<Key, T> value_type; typedef PIPair<Key, T> value_type;
@@ -179,6 +189,9 @@ public:
const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);} const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);}
const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);} const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);}
PIMapIterator<Key, T> makeIterator() const {return PIMapIterator<Key, T>(*this);}
PIMapIterator<Key, T> makeReverseIterator() const {return PIMapIterator<Key, T>(*this, true);}
size_t size() const {return pim_content.size();} size_t size() const {return pim_content.size();}
int size_s() const {return pim_content.size_s();} int size_s() const {return pim_content.size_s();}
size_t length() const {return pim_content.size();} size_t length() const {return pim_content.size();}
@@ -197,14 +210,10 @@ public:
const T at(const Key & key) const {return (*this)[key];} const T at(const Key & key) const {return (*this)[key];}
PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) { PIMap<Key, T> & operator <<(const PIMap<Key, T> & other) {
assert(&other != this);
if (other.isEmpty()) return *this; if (other.isEmpty()) return *this;
if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;} if (other.size() == 1) {insert(other.pim_index[0].key, other.pim_content[0]); return *this;}
if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;} if (other.size() == 2) {insert(other.pim_index[0].key, other.pim_content[0]); insert(other.pim_index[1].key, other.pim_content[1]); return *this;}
/*pim_content << other.pim_content;
size_t si = pim_index.size();
for (int i = 0; i < other.pim_index.size_s(); ++i)
pim_index << MapIndex(other.pim_index[i].key, other.pim_index[i].index + si);
_sort();*/
for (int i = 0; i < other.pim_index.size_s(); ++i) for (int i = 0; i < other.pim_index.size_s(); ++i)
insert(other.pim_index[i].key, other.pim_content[other.pim_index[i].index]); insert(other.pim_index[i].key, other.pim_content[other.pim_index[i].index]);
return *this; return *this;
@@ -213,23 +222,20 @@ public:
bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);} bool operator ==(const PIMap<Key, T> & t) const {return (pim_content == t.pim_content && pim_index == t.pim_index);}
bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);} bool operator !=(const PIMap<Key, T> & t) const {return (pim_content != t.pim_content || pim_index != t.pim_index);}
bool contains(const Key & key) const {bool f(false); _find(key, f); return f;} bool contains(const Key & key) const {bool f(false); _find(key, f); return f;}
//int etries(const T & v) const {int ec = 0; for (size_t i = 0; i < pim_size; ++i) if (v == pim_data[i]) ++ec; return ec;}
PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size); pim_index.reserve(new_size); return *this;} PIMap<Key, T> & reserve(size_t new_size) {pim_content.reserve(new_size); pim_index.reserve(new_size); return *this;}
//PIMap<Key, T> & removeAll(const T & v) {for (llong i = 0; i < pim_size; ++i) if (pim_data[i] == v) {remove(i); --i;} return *this;}
PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;} PIMap<Key, T> & removeOne(const Key & key) {bool f(false); ssize_t i = _find(key, f); if (f) _remove(i); return *this;}
PIMap<Key, T> & remove(const Key & key) {return removeOne(key);} PIMap<Key, T> & remove(const Key & key) {return removeOne(key);}
PIMap<Key, T> & erase(const Key & key) {return removeOne(key);} PIMap<Key, T> & erase(const Key & key) {return removeOne(key);}
PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;} PIMap<Key, T> & clear() {pim_content.clear(); pim_index.clear(); return *this;}
void swap(PIMap<Key, T> & other) { void swap(PIMap<Key, T> & other) {
piSwapBinary<PIVector<T> >(pim_content, other.pim_content); pim_content.swap(other.pim_content);
piSwapBinary<PIDeque<MapIndex> >(pim_index, other.pim_index); pim_index.swap(other.pim_index);
} }
PIMap<Key, T> & insert(const Key & key, const T & value) { PIMap<Key, T> & insert(const Key & key, const T & value) {
//MapIndex * i = _find(key);
bool f(false); bool f(false);
ssize_t i = _find(key, f); ssize_t i = _find(key, f);
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value; //piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
@@ -238,11 +244,21 @@ public:
} else { } else {
pim_content.push_back(value); pim_content.push_back(value);
pim_index.insert(i, MapIndex(key, pim_content.size() - 1)); pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
//_sort();
} }
return *this; return *this;
} }
//const T value(const Key & key, const T & default_ = T()) const {MapIndex * i = _find(key); if (i == 0) return default_; return pim_content[i->index];} PIMap<Key, T> & insert(const Key & key, T && value) {
bool f(false);
ssize_t i = _find(key, f);
//piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value;
if (f) {
pim_content[pim_index[i].index] = std::move(value);
} else {
pim_content.push_back(std::move(value));
pim_index.insert(i, MapIndex(key, pim_content.size() - 1));
}
return *this;
}
const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];} const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];}
PIVector<T> values() const {return pim_content;} PIVector<T> values() const {return pim_content;}
Key key(const T & value_, const Key & default_ = Key()) const {for (int i = 0; i < pim_index.size_s(); ++i) if (pim_content[pim_index[i].index] == value_) return pim_index[i].key; return default_;} Key key(const T & value_, const Key & default_ = Key()) const {for (int i = 0; i < pim_index.size_s(); ++i) if (pim_content[pim_index[i].index] == value_) return pim_index[i].key; return default_;}
@@ -288,12 +304,6 @@ protected:
} }
void _sort() {piQuickSort<MapIndex>(pim_index.data(), pim_index.size_s() - 1);} void _sort() {piQuickSort<MapIndex>(pim_index.data(), pim_index.size_s() - 1);}
ssize_t _find(const Key & k, bool & found) const { ssize_t _find(const Key & k, bool & found) const {
/*for (size_t i = 0; i < pim_index.size(); ++i)
if (pim_index[i].key == k) {
return (MapIndex * )&(pim_index[i]);
}
return 0;*/
//piCout << "find for" << k << pim_index.size_s();
if (pim_index.isEmpty()) { if (pim_index.isEmpty()) {
found = false; found = false;
return 0; return 0;
@@ -309,7 +319,7 @@ protected:
pim_index[i].index = ci; pim_index[i].index = ci;
break; break;
} }
piSwapBinary<T>(pim_content[ci], pim_content.back()); piSwap<T>(pim_content[ci], pim_content.back());
pim_content.resize(pim_index.size()); pim_content.resize(pim_index.size());
} }
const value_type _pair(ssize_t index) const { const value_type _pair(ssize_t index) const {
@@ -324,129 +334,43 @@ protected:
PIVector<T> pim_content; PIVector<T> pim_content;
PIDeque<MapIndex> pim_index; PIDeque<MapIndex> pim_index;
}; };
//template <typename Key, typename T> bool operator <(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key < s.key;}
//template <typename Key, typename T> bool operator >(const typename PIMap<Key, T>::MapIndex & f, const typename PIMap<Key, T>::MapIndex & s) {return f.key > s.key;}
/*#define __PIMAP_SIMPLE_FUNCTIONS__(T) template <typename Key, typename T>
template<> inline PIMap<Key, T>::~PIMap() {dealloc(); _reset();} \ class PIMapIterator {
template<> inline PIMap<Key, T> & PIMap<Key, T>::push_back(const T & v) {alloc(pim_size + 1); pim_data[pim_size - 1] = v; return *this;} \ typedef PIMap<Key, T> MapType;
template<> inline PIMap<Key, T> & PIMap<Key, T>::fill(const T & f) { \
for (size_t i = 0; i < pim_size; ++i) \
pim_data[i] = f; \
return *this; \
} \
template<> inline PIMap<Key, T> & PIMap<Key, T>::resize(size_t new_size, const T & f) { \
if (new_size < pim_size) \
pim_size = new_size; \
if (new_size > pim_size) { \
size_t os = pim_size; \
alloc(new_size); \
for (size_t i = os; i < new_size; ++i) pim_data[i] = f; \
} \
return *this; \
} \
template<> inline PIMap<Key, T> & PIMap<Key, T>::insert(size_t index, const T & v) { \
alloc(pim_size + 1); \
if (index < pim_size - 1) { \
size_t os = pim_size - index - 1; \
memmove(&(pim_data[index + 1]), &(pim_data[index]), os * sizeof(T)); \
} \
pim_data[index] = v; \
return *this; \
} \
template<> inline PIMap<Key, T> & PIMap<Key, T>::remove(size_t index, size_t count) { \
if (index + count >= pim_size) { \
resize(index); \
return *this; \
} \
size_t os = pim_size - index - count; \
memmove(&(pim_data[index]), &(pim_data[index + count]), os * sizeof(T)); \
pim_size -= count; \
return *this; \
}
__PIMAP_SIMPLE_FUNCTIONS__(char)
__PIMAP_SIMPLE_FUNCTIONS__(uchar)
__PIMAP_SIMPLE_FUNCTIONS__(short)
__PIMAP_SIMPLE_FUNCTIONS__(ushort)
__PIMAP_SIMPLE_FUNCTIONS__(int)
__PIMAP_SIMPLE_FUNCTIONS__(uint)
__PIMAP_SIMPLE_FUNCTIONS__(long)
__PIMAP_SIMPLE_FUNCTIONS__(ulong)
__PIMAP_SIMPLE_FUNCTIONS__(llong)
__PIMAP_SIMPLE_FUNCTIONS__(ullong)
__PIMAP_SIMPLE_FUNCTIONS__(float)
__PIMAP_SIMPLE_FUNCTIONS__(double)
__PIMAP_SIMPLE_FUNCTIONS__(ldouble)*/
#else
template<typename Key, typename Type>
class PIP_EXPORT PIMap: public map<Key, Type> {
typedef PIMap<Key, Type> _CMap;
typedef map<Key, Type> _stlc;
typedef std::pair<Key, Type> _stlpair;
public: public:
PIMap() {;} PIMapIterator(const PIMap<Key, T> & map, bool reverse = false): m(map), pos(-1), rev(reverse) {
PIMap(const Key & key_, const Type & value_) {insert(key_, value_);} if (rev) pos = m.size_s();
bool isEmpty() const {return _stlc::empty();}
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
int size_s() const {return static_cast<int>(_stlc::size());}
_CMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
_CMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
Key key(Type value_, const Key & default_ = Key()) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return default_;}
PIVector<Key> keys() const {
PIVector<Key> ret;
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
ret << i->first;
return ret;
} }
Type & at(const Key & key_) {return _stlc::find(key_)->second;} const Key & key() const {return const_cast<MapType & >(m)._key(pos);}
Type value(const Key & key_) const {typename _stlc::const_iterator it = _stlc::find(key_); if (it != _stlc::end()) return it->second; return Type();} const T & value() const {return const_cast<MapType & >(m)._value(pos);}
T & valueRef() const {return const_cast<MapType & >(m)._value(pos);}
inline bool hasNext() const {
if (rev) {
return pos > 0;
} else {
return pos < (m.size_s() - 1);
}
return false;
}
inline bool next() {
if (rev) {
--pos;
return pos >= 0;
} else {
++pos;
return pos < m.size_s();
}
return false;
}
private:
const MapType & m;
ssize_t pos;
bool rev;
}; };
template<typename Key, typename Type>
class PIP_EXPORT PIMultiMap: public multimap<Key, Type> {
typedef PIMultiMap<Key, Type> _CMultiMap;
typedef multimap<Key, Type> _stlc;
typedef std::pair<Key, Type> _stlpair;
public:
PIMultiMap() {;}
PIMultiMap(const Key & key_, const Type & value_) {insert(key_, value_);}
_CMultiMap & insert(const Key & key_, const Type & value_) {_stlc::insert(_stlpair(key_, value_)); return *this;}
_CMultiMap & insert(PIPair<Key, Type> entry_) {_stlc::insert(_stlpair(entry_.first, entry_.second)); return *this;}
bool isEmpty() const {return _stlc::empty();}
bool contains(const Key & key_) const {return _stlc::count(key_) > 0;}
Key key(Type value_, const Key & default_ = Key()) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++) if (i->second == value_) return i->first; return default_;}
PIVector<Key> keys(Type value_) const {
PIVector<Key> ret;
for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); i++)
if (i->second == value_)
ret << i->first;
return ret;
}
Type & value(const Key & key_) {typename _stlc::iterator i = _stlc::find(key_); if (i == _stlc::end()) return Type(); return i->second;}
Type value(const Key & key_) const {typename _stlc::const_iterator i = _stlc::find(key_); if (i == _stlc::end()) return Type(); return i->second;}
PIVector<Type> values(const Key & key_) const {
std::pair<typename _stlc::const_iterator, typename _stlc::const_iterator> range = _stlc::equal_range(key_);
PIVector<Type> ret;
for (typename _stlc::const_iterator i = range.first; i != range.second; ++i)
ret << i->second;
return ret;
}
Type & operator [](const Key & key_) {if (!contains(key_)) return _stlc::insert(_stlpair(key_, Type()))->second; return _stlc::find(key_)->second;}
Type operator [](const Key & key_) const {return _stlc::find(key_)->second;}
};
#define __PIMAP_SIMPLE_FUNCTIONS__(T)
#endif
#ifdef PIP_STD_IOSTREAM #ifdef PIP_STD_IOSTREAM
template<typename Key, typename Type> template<typename Key, typename Type>
inline std::ostream & operator <<(std::ostream & s, const PIMap<Key, Type> & v) { inline std::ostream & operator <<(std::ostream & s, const PIMap<Key, Type> & v) {
@@ -480,5 +404,7 @@ inline PICout operator <<(PICout s, const PIMap<Key, Type> & v) {
return s; return s;
} }
template<typename Key, typename Type> inline void piSwap(PIMap<Key, Type> & f, PIMap<Key, Type> & s) {f.swap(s);}
#endif // PIMAP_H #endif // PIMAP_H

View File

@@ -6,19 +6,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
pair pair
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -30,7 +30,7 @@
class PICout; class PICout;
template<typename Type0, typename Type1> template<typename Type0, typename Type1>
class PIP_EXPORT PIPair { class PIPair {
public: public:
PIPair() {first = Type0(); second = Type1();} PIPair() {first = Type0(); second = Type1();}
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;} PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}

View File

@@ -0,0 +1,51 @@
/*! \file pideque.h
* \brief Queue container
*
* This file declare PIQueue
*/
/*
PIP - Platform Independent Primitives
Queue container
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIQUEUE_H
#define PIQUEUE_H
#include "pideque.h"
#include "pivector.h"
template<typename T>
class PIQueue: public PIDeque<T> {
public:
PIQueue() {}
virtual ~PIQueue() {}
PIDeque<T> & enqueue(const T & v) {PIDeque<T>::push_front(v); return *this;}
PIDeque<T> & enqueue(T && v) {PIDeque<T>::push_front(std::move(v)); return *this;}
T dequeue() {return PIDeque<T>::take_back();}
T & head() {return PIDeque<T>::back();}
const T & head() const {return PIDeque<T>::back();}
PIVector<T> toVector() {
PIVector<T> v;
v.reserve(PIDeque<T>::size());
for (uint i = 0; i < PIDeque<T>::size(); ++i)
v.push_back(PIDeque<T>::at(i));
return v;
}
};
#endif // PIQUEUE_H

View File

@@ -6,19 +6,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Set container Set container
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -35,7 +35,7 @@
* has logarithmic complexity. * has logarithmic complexity.
*/ */
template <typename T> template <typename T>
class PIP_EXPORT PISet: public PIMap<T, uchar> { class PISet: public PIMap<T, uchar> {
typedef PIMap<T, uchar> _CSet; typedef PIMap<T, uchar> _CSet;
public: public:
@@ -59,32 +59,23 @@ public:
//! Contructs set from vector of elements //! Contructs set from vector of elements
PISet(const PIVector<T> & values) { PISet(const PIVector<T> & values) {
if (values.isEmpty()) return; if (values.isEmpty()) return;
//_CSet::pim_content.resize(values.size_s());
//_CSet::pim_index.resize(values.size_s());
for (int i = 0; i < values.size_s(); ++i) { for (int i = 0; i < values.size_s(); ++i) {
//_CSet::pim_index[i].index = i;
//_CSet::pim_index[i].key = values[i];
_CSet::insert(values[i], 0); _CSet::insert(values[i], 0);
} }
//_CSet::_sort();
} }
//! Contructs set from deque of elements //! Contructs set from deque of elements
PISet(const PIDeque<T> & values) { PISet(const PIDeque<T> & values) {
if (values.isEmpty()) return; if (values.isEmpty()) return;
//_CSet::pim_content.resize(values.size_s());
//_CSet::pim_index.resize(values.size_s());
for (int i = 0; i < values.size_s(); ++i) { for (int i = 0; i < values.size_s(); ++i) {
//_CSet::pim_index[i].index = i;
//_CSet::pim_index[i].key = values[i];
_CSet::insert(values[i], 0); _CSet::insert(values[i], 0);
} }
//_CSet::_sort();
} }
typedef T key_type; typedef T key_type;
PISet<T> & operator <<(const T & t) {_CSet::insert(t, 0); return *this;} PISet<T> & operator <<(const T & t) {_CSet::insert(t, 0); return *this;}
PISet<T> & operator <<(T && t) {_CSet::insert(std::move(t), 0); return *this;}
PISet<T> & operator <<(const PISet<T> & other) {(*(_CSet*)this) << *((_CSet*)&other); return *this;} PISet<T> & operator <<(const PISet<T> & other) {(*(_CSet*)this) << *((_CSet*)&other); return *this;}
//! Returns if element "t" exists in this set //! Returns if element "t" exists in this set

View File

@@ -0,0 +1,49 @@
/*! \file pistack.h
* \brief Stack container
*
* This file declare PIStack
*/
/*
PIP - Platform Independent Primitives
Stack container
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PISTACK_H
#define PISTACK_H
#include "pivector.h"
template<typename T>
class PIStack: public PIVector<T> {
public:
PIStack() {;}
virtual ~PIStack() {;}
PIVector<T> & push(const T & v) {PIVector<T>::push_back(v); return *this;}
PIVector<T> & push(T && v) {PIVector<T>::push_back(std::move(v)); return *this;}
T pop() {return PIVector<T>::take_back();}
T & top() {return PIVector<T>::back();}
const T & top() const {return PIVector<T>::back();}
PIVector<T> toVector() {
PIVector<T> v;
v.reserve(PIVector<T>::size());
for (uint i = 0; i < PIVector<T>::size(); ++i)
v.push_back(PIVector<T>::at(i));
return v;
}
};
#endif // PISTACK_H

View File

@@ -6,19 +6,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Dynamic array of any type Dynamic array of any type
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -28,9 +28,6 @@
#include "picontainers.h" #include "picontainers.h"
#if !defined(PIP_CONTAINERS_STL) || defined(DOXYGEN)
template <typename T> template <typename T>
class PIVector { class PIVector {
public: public:
@@ -51,6 +48,9 @@ public:
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
resize(piv_size, f); resize(piv_size, f);
} }
inline PIVector(PIVector<T> && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) {
other._reset();
}
inline virtual ~PIVector() { inline virtual ~PIVector() {
PIINTROSPECTION_CONTAINER_DELETE(T) PIINTROSPECTION_CONTAINER_DELETE(T)
PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize)) PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize))
@@ -68,6 +68,11 @@ public:
return *this; return *this;
} }
inline PIVector<T> & operator =(PIVector<T> && other) {
swap(other);
return *this;
}
typedef T value_type; typedef T value_type;
class iterator { class iterator {
@@ -256,6 +261,16 @@ public:
elementNew(piv_data + index, v); elementNew(piv_data + index, v);
return *this; return *this;
} }
inline PIVector<T> & insert(size_t index, T && v) {
alloc(piv_size + 1);
if (index < piv_size - 1) {
size_t os = piv_size - index - 1;
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
}
PIINTROSPECTION_CONTAINER_USED(T, 1)
elementNew(piv_data + index, std::move(v));
return *this;
}
inline PIVector<T> & insert(size_t index, const PIVector<T> & other) { inline PIVector<T> & insert(size_t index, const PIVector<T> & other) {
if (other.isEmpty()) return *this; if (other.isEmpty()) return *this;
assert(&other != this); assert(&other != this);
@@ -323,7 +338,14 @@ public:
elementNew(piv_data + piv_size - 1, v); elementNew(piv_data + piv_size - 1, v);
return *this; return *this;
} }
inline PIVector<T> & push_back(T && v) {
alloc(piv_size + 1);
PIINTROSPECTION_CONTAINER_USED(T, 1);
elementNew(piv_data + piv_size - 1, std::move(v));
return *this;
}
inline PIVector<T> & append(const T & v) {return push_back(v);} inline PIVector<T> & append(const T & v) {return push_back(v);}
inline PIVector<T> & append(T && v) {return push_back(std::move(v));}
inline PIVector<T> & append(const PIVector<T> & other) { inline PIVector<T> & append(const PIVector<T> & other) {
assert(&other != this); assert(&other != this);
size_t ps = piv_size; size_t ps = piv_size;
@@ -332,10 +354,13 @@ public:
return *this; return *this;
} }
inline PIVector<T> & operator <<(const T & v) {return push_back(v);} inline PIVector<T> & operator <<(const T & v) {return push_back(v);}
inline PIVector<T> & operator <<(T && v) {return push_back(std::move(v));}
inline PIVector<T> & operator <<(const PIVector<T> & other) {return append(other);} inline PIVector<T> & operator <<(const PIVector<T> & other) {return append(other);}
inline PIVector<T> & push_front(const T & v) {insert(0, v); return *this;} inline PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
inline PIVector<T> & push_front(T && v) {insert(0, std::move(v)); return *this;}
inline PIVector<T> & prepend(const T & v) {return push_front(v);} inline PIVector<T> & prepend(const T & v) {return push_front(v);}
inline PIVector<T> & prepend(T && v) {return push_front(std::move(v));}
inline PIVector<T> & pop_back() { inline PIVector<T> & pop_back() {
if (piv_size == 0) if (piv_size == 0)
@@ -361,7 +386,6 @@ public:
return ret; return ret;
} }
#ifdef PIP_CXX11_SUPPORT
const PIVector<T> & forEach(std::function<void(const T &)> f) const { const PIVector<T> & forEach(std::function<void(const T &)> f) const {
for (uint i = 0; i < piv_size; ++i) for (uint i = 0; i < piv_size; ++i)
f(piv_data[i]); f(piv_data[i]);
@@ -385,7 +409,6 @@ public:
ret << f(piv_data[i]); ret << f(piv_data[i]);
return ret; return ret;
} }
#endif
private: private:
inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;} inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;}
@@ -410,6 +433,7 @@ private:
} }
} }
inline void elementNew(T * to, const T & from) {new(to)T(from);} inline void elementNew(T * to, const T & from) {new(to)T(from);}
inline void elementNew(T * to, T && from) {new(to)T(std::move(from));}
inline void elementDelete(T & from) {from.~T();} inline void elementDelete(T & from) {from.~T();}
inline void dealloc() { inline void dealloc() {
if ((uchar*)piv_data != 0) free((uchar*)piv_data); if ((uchar*)piv_data != 0) free((uchar*)piv_data);
@@ -439,6 +463,7 @@ private:
template<> inline void PIVector<T>::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIVector<T>::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \
template<> inline void PIVector<T>::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIVector<T>::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \
template<> inline void PIVector<T>::elementNew(T * to, const T & from) {(*to) = from;} \ template<> inline void PIVector<T>::elementNew(T * to, const T & from) {(*to) = from;} \
template<> inline void PIVector<T>::elementNew(T * to, T && from) {(*to) = std::move(from);} \
template<> inline void PIVector<T>::elementDelete(T &) {;} \ template<> inline void PIVector<T>::elementDelete(T &) {;} \
template<> inline PIVector<T> & PIVector<T>::_resizeRaw(size_t new_size) { \ template<> inline PIVector<T> & PIVector<T>::_resizeRaw(size_t new_size) { \
if (new_size > piv_size) { \ if (new_size > piv_size) { \
@@ -454,93 +479,6 @@ private:
template<> inline PIVector<T> & PIVector<T>::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);} template<> inline PIVector<T> & PIVector<T>::assign(size_t new_size, const T & f) {_resizeRaw(new_size); return fill(f);}
#else
template<typename T, typename Allocator = std::allocator<T> >
class PIP_EXPORT PIVector: public vector<T, Allocator> {
typedef PIVector<T, Allocator> _CVector;
typedef vector<T, Allocator> _stlc;
public:
PIVector() {}
PIVector(uint size, const T & value = T()) {_stlc::resize(size, value);}
~PIVector() {}
const T & at(uint index) const {return (*this)[index];}
T & at(uint index) {return (*this)[index];}
const T * data(uint index = 0) const {return &(*this)[index];}
T * data(uint index = 0) {return &(*this)[index];}
#ifdef DOXYGEN
uint size() const;
#endif
int size_s() const {return static_cast<int>(_stlc::size());}
bool isEmpty() const {return _stlc::empty();}
bool has(const T & t) const {for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) return true; return false;}
int etries(const T & t) const {int ec = 0; for (typename _stlc::const_iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (t == *i) ++ec; return ec;}
typedef int (*CompareFunc)(const T * , const T * );
static int compare_func(const T * t0, const T * t1) {return (*t0) == (*t1) ? 0 : ((*t0) < (*t1) ? -1 : 1);}
#ifdef DOXYGEN
void resize(uint size, const T & new_type = T());
PIVector<T, Allocator> & enlarge(uint size);
void clear();
PIVector<T, Allocator> & sort(CompareFunc compare = compare_func) {piqsort(&at(0), _stlc::size(), sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
PIVector<T, Allocator> & fill(const T & t) {_stlc::assign(_stlc::size(), t); return *this;}
T & back();
const T & back() const;
T & front();
const T & front() const;
PIVector<T, Allocator> & push_back(const T & t);
PIVector<T, Allocator> & push_front(const T & t) {_stlc::insert(_stlc::begin(), t); return *this;}
PIVector<T, Allocator> & pop_back();
PIVector<T, Allocator> & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
T take_back() {T t(_stlc::back()); _stlc::pop_back(); return t;}
T take_front() {T t(_stlc::front()); pop_front(); return t;}
PIVector<T, Allocator> & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
PIVector<T, Allocator> & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
PIVector<T, Allocator> & removeOne(const T & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
PIVector<T, Allocator> & removeAll(const T & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
PIVector<T, Allocator> & insert(uint pos, const T & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
PIVector<T, Allocator> & insert(uint pos, const PIVector<T, Allocator> & t) {_stlc::insert(_stlc::begin() + pos, t.begin(), t.end()); return *this;}
T & operator [](uint index);
const T & operator [](uint index) const;
PIVector<T, Allocator> & operator <<(const T & t) {_stlc::push_back(t); return *this;}
PIVector<T, Allocator> & operator <<(const PIVector<T, Allocator> & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
bool operator ==(const PIVector<T, Allocator> & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
bool operator !=(const PIVector<T, Allocator> & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
bool contains(const T & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
#else
_CVector & enlarge(int size_) {int ns = size_s() + size_; if (ns <= 0) _stlc::clear(); else _stlc::resize(ns); return *this;}
_CVector & sort(CompareFunc compare = compare_func) {piqsort(&at(0), _stlc::size(), sizeof(T), (int(*)(const void * , const void * ))compare); return *this;}
_CVector & fill(const T & t) {_stlc::assign(_stlc::size(), t); return *this;}
_CVector & pop_front() {_stlc::erase(_stlc::begin()); return *this;}
_CVector & push_front(const T & t) {_stlc::insert(_stlc::begin(), t); return *this;}
T take_front() {T t(_stlc::front()); pop_front(); return t;}
T take_back() {T t(_stlc::back()); _stlc::pop_back(); return t;}
_CVector & remove(uint index) {_stlc::erase(_stlc::begin() + index); return *this;}
_CVector & remove(uint index, uint count) {_stlc::erase(_stlc::begin() + index, _stlc::begin() + index + count); return *this;}
_CVector & removeOne(const T & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); return *this;} return *this;}
_CVector & removeAll(const T & v) {for (typename _stlc::iterator i = _stlc::begin(); i != _stlc::end(); ++i) if (v == *i) {_stlc::erase(i); --i;} return *this;}
_CVector & insert(uint pos, const T & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;}
_CVector & insert(uint pos, const _CVector & t) {_stlc::insert(_stlc::begin() + pos, t.begin(), t.end()); return *this;}
_CVector & operator <<(const T & t) {_stlc::push_back(t); return *this;}
_CVector & operator <<(const _CVector & t) {for (typename _stlc::const_iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;}
bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;}
bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;}
bool contains(const T & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;}
#endif
};
#define __PIVECTOR_SIMPLE_TYPE__(T)
#endif
__PIVECTOR_SIMPLE_TYPE__(bool) __PIVECTOR_SIMPLE_TYPE__(bool)
__PIVECTOR_SIMPLE_TYPE__(char) __PIVECTOR_SIMPLE_TYPE__(char)
__PIVECTOR_SIMPLE_TYPE__(uchar) __PIVECTOR_SIMPLE_TYPE__(uchar)
@@ -577,5 +515,7 @@ inline PICout operator <<(PICout s, const PIVector<T> & v) {
return s; return s;
} }
template<typename T> inline void piSwap(PIVector<T> & f, PIVector<T> & s) {f.swap(s);}
#endif // PIVECTOR_H #endif // PIVECTOR_H

View File

@@ -6,19 +6,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
2D wrapper around PIVector 2D wrapper around PIVector
Copyright (C) 2020 Andrey Bychkov work.a.b@yandex.ru Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -44,10 +44,10 @@ public:
cols_ = cols; cols_ = cols;
mat.resize(rows*cols, f); mat.resize(rows*cols, f);
} }
inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v) { inline PIVector2D(size_t rows, size_t cols, const PIVector<T> & v) : rows_(rows), cols_(cols), mat(v) {
mat = v; mat.resize(rows*cols);
rows_ = rows; }
cols_ = cols; inline PIVector2D(size_t rows, size_t cols, PIVector<T> && v) : rows_(rows), cols_(cols), mat(std::move(v)) {
mat.resize(rows*cols); mat.resize(rows*cols);
} }
inline PIVector2D(const PIVector<PIVector<T> > & v) { inline PIVector2D(const PIVector<PIVector<T> > & v) {
@@ -212,8 +212,31 @@ public:
return *this; return *this;
} }
inline PIVector2D<T> & resize(size_t rows, size_t cols, const T & f = T()) {
mat.resize(rows*cols_, f);
rows_ = rows;
int cs = (cols - cols_);
if (cs < 0) {
for (size_t r=0; r<rows; ++r) {
mat.remove(r*cols_ + cols_, -cs);
}
}
mat.resize(rows*cols, f);
if (!mat.isEmpty()) {
if (cs > 0) {
for (size_t r=0; r<rows_; ++r) {
for (int i=0; i<cs; ++i)
mat.insert(r*cols + cols_, mat.take_back());
}
}
}
cols_ = cols;
return *this;
}
PIVector<PIVector<T> > toVectors() const { PIVector<PIVector<T> > toVectors() const {
PIVector<PIVector<T> > ret; PIVector<PIVector<T> > ret;
ret.reserve(rows_);
for(size_t i = 0; i < rows_; ++i) for(size_t i = 0; i < rows_; ++i)
ret << PIVector<T>(mat.data(i*cols_), cols_); ret << PIVector<T>(mat.data(i*cols_), cols_);
return ret; return ret;

View File

@@ -7,19 +7,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Base types and functions Base types and functions
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -94,14 +94,9 @@
//! Macro is defined when PIP can use "rt" library for "PITimer::ThreadRT" timers implementation //! Macro is defined when PIP can use "rt" library for "PITimer::ThreadRT" timers implementation
# define PIP_TIMER_RT # define PIP_TIMER_RT
//! Define this macro to use STL implementation of containers, else PIP implementation will be used
# define PIP_CONTAINERS_STL
#endif #endif
#ifdef PIP_CXX11_SUPPORT #include <functional>
# include <functional>
#endif
#include <cstddef> #include <cstddef>
#ifdef WINDOWS #ifdef WINDOWS
@@ -197,10 +192,10 @@
// Private data macros // Private data macros
#define PRIVATE_DECLARATION \ #define PRIVATE_DECLARATION(e) \
struct __Private__; \ struct __Private__; \
friend struct __Private__; \ friend struct __Private__; \
struct __PrivateInitializer__ { \ struct e __PrivateInitializer__ { \
__PrivateInitializer__(); \ __PrivateInitializer__(); \
__PrivateInitializer__(const __PrivateInitializer__ & o); \ __PrivateInitializer__(const __PrivateInitializer__ & o); \
~__PrivateInitializer__(); \ ~__PrivateInitializer__(); \
@@ -215,16 +210,16 @@
#define PRIVATE_DEFINITION_END(c) \ #define PRIVATE_DEFINITION_END(c) \
}; \ }; \
c::__PrivateInitializer__::__PrivateInitializer__() {p = new c::__Private__();} \ c::__PrivateInitializer__::__PrivateInitializer__() {p = new c::__Private__();} \
c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ & o) {/*if (p) delete p;*/ p = new c::__Private__();} \ c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ & ) {/*if (p) delete p;*/ p = new c::__Private__();} \
c::__PrivateInitializer__::~__PrivateInitializer__() {delete p; p = 0;} \ c::__PrivateInitializer__::~__PrivateInitializer__() {delete p; p = 0;} \
c::__PrivateInitializer__ & c::__PrivateInitializer__::operator =(const c::__PrivateInitializer__ & o) {if (p) delete p; p = new c::__Private__(); return *this;} c::__PrivateInitializer__ & c::__PrivateInitializer__::operator =(const c::__PrivateInitializer__ & ) {if (p) delete p; p = new c::__Private__(); return *this;}
#define PRIVATE (__privateinitializer__.p) #define PRIVATE (__privateinitializer__.p)
#define PRIVATEWB __privateinitializer__.p #define PRIVATEWB __privateinitializer__.p
#define NO_COPY_CLASS(name) \ #define NO_COPY_CLASS(name) \
explicit name(const name & ); \ name(const name&) = delete; \
void operator =(const name & ); name& operator=(const name&) = delete;
#ifdef FREERTOS #ifdef FREERTOS
# define PIP_MIN_MSLEEP 10. # define PIP_MIN_MSLEEP 10.
@@ -260,7 +255,7 @@ typedef long double ldouble;
/*! \brief Templated function for swap two values /*! \brief Templated function for swap two values
* \details Example:\n \snippet piincludes.cpp swap */ * \details Example:\n \snippet piincludes.cpp swap */
template<typename T> inline void piSwap(T & f, T & s) {T t = f; f = s; s = t;} template<typename T> inline void piSwap(T & f, T & s) {T t(std::move(f)); f = std::move(s); s = std::move(t);}
/*! \brief Templated function for swap two values without "=" /*! \brief Templated function for swap two values without "="
* \details Example:\n \snippet piincludes.cpp swapBinary */ * \details Example:\n \snippet piincludes.cpp swapBinary */
@@ -297,6 +292,14 @@ template<> inline void piSwapBinary(const void *& f, const void *& s) {
} }
} }
template<> inline void piSwap(double & f, double & s) {piSwapBinary<double>(f, s);}
template<> inline void piSwap(ldouble & f, ldouble & s) {piSwapBinary<ldouble>(f, s);}
#ifdef ARCH_BITS_32
template<> inline void piSwap(float & f, float & s) {piSwapBinary<float>(f, s);}
template<> inline void piSwap(llong & f, llong & s) {piSwapBinary<llong>(f, s);}
template<> inline void piSwap(ullong & f, ullong & s) {piSwapBinary<ullong>(f, s);}
#endif
/*! \brief Function for compare two values without "=" by raw content /*! \brief Function for compare two values without "=" by raw content
* \details Example:\n \snippet piincludes.cpp compareBinary */ * \details Example:\n \snippet piincludes.cpp compareBinary */
inline bool piCompareBinary(const void * f, const void * s, size_t size) { inline bool piCompareBinary(const void * f, const void * s, size_t size) {

View File

@@ -0,0 +1,44 @@
/*
PIP - Platform Independent Primitives
Bit array
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pibitarray.h"
#include "picout.h"
PICout operator <<(PICout s, const PIBitArray & ba) {
s.space();
s.setControl(0, true);
for (uint i = 0; i < ba.bitSize(); ++i) {
s << int(ba[i]);
if (i % 8 == 7) s << ' ';
}
s.restoreControl();
return s;
}
#ifdef PIP_STD_IOSTREAM
std::ostream &operator <<(std::ostream & s, const PIBitArray & ba) {
for (uint i = 0; i < ba.bitSize(); ++i) {
s << ba[i];
if (i % 8 == 7) s << ' ';
}
return s;
}
#endif

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Bit array Bit array
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,24 +1,24 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Byte array Byte array
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "pibytearray.h" #include "pibytearray.h"
#include "pistring.h" #include "pistringlist.h"
#include <iostream> #include <iostream>
/*! \class PIByteArray /*! \class PIByteArray

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Byte array Byte array
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -56,6 +56,10 @@ public:
//! Constructs an empty byte array //! Constructs an empty byte array
PIByteArray() {;} PIByteArray() {;}
PIByteArray(const PIByteArray & o): PIDeque<uchar>(o) {}
PIByteArray(PIByteArray && o): PIDeque<uchar>(std::move(o)) {}
//! Constructs 0-filled byte array with size "size" //! Constructs 0-filled byte array with size "size"
PIByteArray(const uint size) {resize(size);} PIByteArray(const uint size) {resize(size);}
@@ -124,6 +128,10 @@ public:
void operator =(const PIDeque<uchar> & d) {resize(d.size()); memcpy(data(), d.data(), d.size());} void operator =(const PIDeque<uchar> & d) {resize(d.size()); memcpy(data(), d.data(), d.size());}
PIByteArray & operator =(const PIByteArray & o) {if (this == &o) return *this; clear(); append(o); return *this;}
PIByteArray & operator =(PIByteArray && o) {swap(o); return *this;}
static PIByteArray fromUserInput(PIString str); static PIByteArray fromUserInput(PIString str);
static PIByteArray fromHex(PIString str); static PIByteArray fromHex(PIString str);
static PIByteArray fromBase64(const PIByteArray & base64); static PIByteArray fromBase64(const PIByteArray & base64);
@@ -138,7 +146,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);
#endif #endif
//! \relatesalso PIByteArray \brief Output to PICout operator //! \relatesalso PIByteArray \brief Output to PICout operator
PICout operator <<(PICout s, const PIByteArray & ba); PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba);
#define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); #define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v));
@@ -212,7 +220,7 @@ inline PIByteArray & operator >>(PIByteArray & s, ldouble & v) {assert(s.size()
//! \relatesalso PIByteArray \brief Restore operator //! \relatesalso PIByteArray \brief Restore operator
template<typename T> inline PIByteArray & operator >>(PIByteArray & s, PIFlags<T> & v) {PBA_OPERATOR_FROM return s;} template<typename T> inline PIByteArray & operator >>(PIByteArray & s, PIFlags<T> & v) {PBA_OPERATOR_FROM return s;}
//! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details
PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v);
//! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details
inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy((void*)(v.d), s.data(), v.s); s.remove(0, v.s); return s;} inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy((void*)(v.d), s.data(), v.s); s.remove(0, v.s); return s;}
@@ -301,7 +309,6 @@ inline bool operator !=(PIByteArray & f, PIByteArray & s) {if (f.size_s() != s.s
__PIBYTEARRAY_SIMPLE_TYPE__(bool) __PIBYTEARRAY_SIMPLE_TYPE__(bool)
__PIBYTEARRAY_SIMPLE_TYPE__(char) __PIBYTEARRAY_SIMPLE_TYPE__(char)
//__PIBYTEARRAY_SIMPLE_TYPE__(uchar)
__PIBYTEARRAY_SIMPLE_TYPE__(short) __PIBYTEARRAY_SIMPLE_TYPE__(short)
__PIBYTEARRAY_SIMPLE_TYPE__(ushort) __PIBYTEARRAY_SIMPLE_TYPE__(ushort)
__PIBYTEARRAY_SIMPLE_TYPE__(int) __PIBYTEARRAY_SIMPLE_TYPE__(int)
@@ -317,6 +324,7 @@ __PIBYTEARRAY_SIMPLE_TYPE__(PIChar)
template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();} template<> inline uint piHash(const PIByteArray & ba) {return ba.hash();}
template<> inline void piSwap(PIByteArray & f, PIByteArray & s) {f.swap(s);}
#endif // PIBYTEARRAY_H #endif // PIBYTEARRAY_H

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Unicode char Unicode char
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -75,7 +75,6 @@ ushort charFromCodepage(const char * c, int size, const char * codepage, int * t
if (ret <= 0) return 0; if (ret <= 0) return 0;
if (taken) *taken = ret; if (taken) *taken = ret;
return buffer; return buffer;
//printf("request %d\n", sz);
# else # else
wchar_t wc(0); wchar_t wc(0);
mbtowc(0, 0, 0); // reset mbtowc mbtowc(0, 0, 0); // reset mbtowc
@@ -378,10 +377,7 @@ PICout operator <<(PICout s, const PIChar & v) {
} else } else
#endif #endif
#ifdef WINDOWS #ifdef WINDOWS
//if (PICout::isBufferActive())
s << v.toSystem(); s << v.toSystem();
//else
// s << v.toConsole1Byte();
#else #else
{ {
char tc[8]; char tc[8];

37
src_main/core/pichar.h → lib/main/core/pichar.h Executable file → Normal file
View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Unicode char Unicode char
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -25,9 +25,9 @@
#include "piincludes.h" #include "piincludes.h"
extern char * __syslocname__; extern PIP_EXPORT char * __syslocname__;
extern char * __sysoemname__; extern PIP_EXPORT char * __sysoemname__;
extern char * __utf8name__; extern PIP_EXPORT char * __utf8name__;
class PIP_EXPORT PIChar class PIP_EXPORT PIChar
{ {
@@ -57,37 +57,14 @@ public:
//! Contructs symbol from no more than 4 bytes of string //! Contructs symbol from no more than 4 bytes of string
PIChar(const char * c, int * bytes = 0); PIChar(const char * c, int * bytes = 0);
//inline operator const int() {return static_cast<const int>(ch);}
//inline operator const char() {return toAscii();}
//! Copy operator //! Copy operator
PIChar & operator =(const char v) {ch = v; return *this;} PIChar & operator =(const char v) {ch = v; return *this;}
/*inline PIChar & operator =(const short v) {ch = v; return *this;}
inline PIChar & operator =(const int v) {ch = v; return *this;}
inline PIChar & operator =(const uchar v) {ch = v; return *this;}
inline PIChar & operator =(const ushort v) {ch = v; return *this;}
inline PIChar & operator =(const uint v) {ch = v; return *this;}*/
//! Compare operator //! Compare operator
bool operator ==(const PIChar & o) const; bool operator ==(const PIChar & o) const;
/*inline bool operator ==(const PIChar & o) const {if (o.isAscii() ^ isAscii()) return false;
if (isAscii()) return (o.toAscii() == toAscii());
return (o.toInt() == toInt());}
inline bool operator ==(const char o) const {return (PIChar(o) == *this);}
inline bool operator ==(const short o) const {return (PIChar(o) == *this);}
inline bool operator ==(const int o) const {return (PIChar(o) == *this);}
inline bool operator ==(const uchar o) const {return (PIChar(o) == *this);}
inline bool operator ==(const ushort o) const {return (PIChar(o) == *this);}
inline bool operator ==(const uint o) const {return (PIChar(o) == *this);}*/
//! Compare operator //! Compare operator
bool operator !=(const PIChar & o) const {return !(o == *this);} bool operator !=(const PIChar & o) const {return !(o == *this);}
/*inline bool operator !=(const char o) const {return (PIChar(o) != *this);}
inline bool operator !=(const short o) const {return (PIChar(o) != *this);}
inline bool operator !=(const int o) const {return (PIChar(o) != *this);}
inline bool operator !=(const uchar o) const {return (PIChar(o) != *this);}
inline bool operator !=(const ushort o) const {return (PIChar(o) != *this);}
inline bool operator !=(const uint o) const {return (PIChar(o) != *this);}*/
//! Compare operator //! Compare operator
bool operator >(const PIChar & o) const; bool operator >(const PIChar & o) const;

View File

@@ -1,3 +1,22 @@
/*
PIP - Platform Independent Primitives
Binary markup serializator
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pichunkstream.h" #include "pichunkstream.h"
/*! \class PIChunkStream /*! \class PIChunkStream
@@ -99,7 +118,6 @@ uint PIChunkStream::readVInt(PIByteArray & s) {
for (abc = 0; abc < 3; ++abc) { for (abc = 0; abc < 3; ++abc) {
uchar mask = (0x80 >> abc); uchar mask = (0x80 >> abc);
if ((bytes[0] & mask) == mask) { if ((bytes[0] & mask) == mask) {
//if (s.isEmpty()) return 0;
bytes[0] &= (mask - 1); bytes[0] &= (mask - 1);
s >> bytes[abc + 1]; s >> bytes[abc + 1];
} else break; } else break;

View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Binary markup serializator Binary markup serializator
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -54,12 +54,18 @@ public:
int id; int id;
T data; T data;
}; };
template <typename T>
struct ChunkConst {
ChunkConst(int i, const T & d): id(i), data(d) {}
int id;
const T & data;
};
//! Returns chunk with ID "id" and value "data" for write to stream //! Returns chunk with ID "id" and value "data" for write to stream
template <typename T> static Chunk<T> chunk(int id, const T & data) {return Chunk<T>(id, data);} template <typename T> static ChunkConst<T> chunk(int id, const T & data) {return ChunkConst<T>(id, data);}
//! Add data to this chunk strean with ID "id" and value "data" //! Add data to this chunk strean with ID "id" and value "data"
template <typename T> PIChunkStream & add(int id, const T & data) {*this << Chunk<T>(id, data); return *this;} template <typename T> PIChunkStream & add(int id, const T & data) {*this << ChunkConst<T>(id, data); return *this;}
void setSource(const PIByteArray & data); void setSource(const PIByteArray & data);
void setSource(PIByteArray * data); void setSource(PIByteArray * data);
@@ -112,6 +118,7 @@ private:
PIMap<int, PIByteArray> data_map; PIMap<int, PIByteArray> data_map;
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c); template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c);
template <typename T> friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c);
}; };
template <typename T> template <typename T>
@@ -133,5 +140,24 @@ PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk<T> & c
} }
return s; return s;
} }
template <typename T>
PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst<T> & c) {
PIByteArray ba;
ba << c.data;
switch (s.version_) {
case PIChunkStream::Version_1:
(*(s.data_)) << c.id << ba;
break;
case PIChunkStream::Version_2:
if (s.data_->isEmpty())
(*(s.data_)) << uchar(uchar(s.version_) | 0x80);
PIChunkStream::writeVInt(*(s.data_), c.id);
PIChunkStream::writeVInt(*(s.data_), ba.size());
s.data_->append(ba);
break;
default: break;
}
return s;
}
#endif // PICHUNKSTREAM_H #endif // PICHUNKSTREAM_H

8
src_main/core/picli.cpp → lib/main/core/picli.cpp Executable file → Normal file
View File

@@ -1,19 +1,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Command-Line Parser Command-Line Parser
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

8
src_main/core/picli.h → lib/main/core/picli.h Executable file → Normal file
View File

@@ -4,19 +4,19 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Command-Line Parser Command-Line Parser
Copyright (C) 2020 Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */

View File

@@ -1,3 +1,22 @@
/*
PIP - Platform Independent Primitives
Peer - named I/O ethernet node, forming self-organized peering network
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "picollection.h" #include "picollection.h"

Some files were not shown because too many files have changed in this diff Show More