12 Commits

Author SHA1 Message Date
62c5523127 direct wchar_t output to PIScreen on Windows works 2025-09-24 18:34:01 +03:00
daab41e41e add options for fftw3 precisions
configureFromFullPathDevice for all devices now trim() components
2025-09-23 21:16:54 +03:00
a61c8477c7 fix PIMap operator<<(PIMap) error for size=2 2025-09-22 22:34:06 +03:00
788ad8f2c0 PIVariant::toNum from mathvector safety fix 2025-09-22 20:58:58 +03:00
78afc179c4 PIVariant::toNum now from mathvector 2025-09-22 16:26:09 +03:00
69ec4c9837 .clang-format 2025-09-21 21:08:18 +03:00
2368de6e93 rename PRIVATE_DEFINITION_FINISH to PRIVATE_DEFINITION_END_NO_INITIALIZE 2025-09-21 21:05:56 +03:00
e5df76ab1d decompose PRIVATE_DEFINITION_END(c) to PRIVATE_DEFINITION_FINISH(c) and RIVATE_DEFINITION_INITIALIZE(c)
now you can define private in separate file and initialize it in main cpp
2025-09-19 17:39:39 +03:00
fdec0e66a8 Merge pull request 'codeparser_C' (#192) from codeparser_C into master
Reviewed-on: #192
2025-09-18 20:19:11 +03:00
5f3baa5580 PICODEINFO::accessOffsetFunction
add offset generation in pip_cmg for retrieve bytes offset of struct member
add pip_cmg -V doc
2025-09-18 17:12:35 +03:00
7083b2c32b finish codeparser improvements
pip_cmg now works with new nested entities approach
Getters now can access to bitfields
2025-09-18 05:54:31 +03:00
af02684dc5 adopt PICodeParser for C-style typedefs and some other 2025-09-17 19:42:00 +03:00
29 changed files with 542 additions and 587 deletions

View File

@@ -135,7 +135,7 @@ JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: "PRIVATE_DEFINITION_START|STATIC_INITIALIZER_BEGIN"
MacroBlockEnd: "PRIVATE_DEFINITION_END|STATIC_INITIALIZER_END"
MacroBlockEnd: "PRIVATE_DEFINITION_END|PRIVATE_DEFINITION_END_NO_INITIALIZE|STATIC_INITIALIZER_END"
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto

View File

@@ -5,8 +5,8 @@ if (POLICY CMP0177)
endif()
project(PIP)
set(PIP_MAJOR 5)
set(PIP_MINOR 2)
set(PIP_REVISION 1)
set(PIP_MINOR 3)
set(PIP_REVISION 0)
set(PIP_SUFFIX )
set(PIP_COMPANY SHS)
set(PIP_DOMAIN org.SHS)
@@ -69,6 +69,9 @@ option(STD_IOSTREAM "Building with std iostream operators support" OFF)
option(INTROSPECTION "Build with introspection" OFF)
option(TESTS "Build tests and perform their before install step" OFF)
option(COVERAGE "Build project with coverage info" OFF)
option(PIP_FFTW_F "Support fftw module for float" ON)
option(PIP_FFTW_L "Support fftw module for long double" ON)
option(PIP_FFTW_Q "Support fftw module for quad double" OFF)
set(PIP_UTILS 1)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
set(CMAKE_CXX_STANDARD 11)
@@ -436,8 +439,23 @@ if (NOT CROSSTOOLS)
if (PIP_BUILD_FFTW)
# Check if PIP support fftw3 for PIFFT using in math module
set(FFTW_LIB_NAME fftw3)
set(FFTW_LIB_SUFFIXES "" "f" "l" "q")
set(FFTW_LIB_SUFFIXES "")
if (PIP_FFTW_F)
list(APPEND FFTW_LIB_SUFFIXES "f")
endif()
if (PIP_FFTW_L)
list(APPEND FFTW_LIB_SUFFIXES "l")
endif()
if (PIP_FFTW_Q)
list(APPEND FFTW_LIB_SUFFIXES "q")
endif()
if (NOT "${FFTW_LIB_SUFFIXES}" STREQUAL "")
set(FFTW_LIB_SUFFIXES ";${FFTW_LIB_SUFFIXES}")
else()
list(APPEND FFTW_LIB_SUFFIXES "" "_")
endif()
set(FFTW_LIB_SUFFIXES2 "" "-3")
set(FFTW_MSG "")
set(FFTW_LIBS)
set(FFTW_ABS_LIBS)
set(CMAKE_REQUIRED_INCLUDES fftw3.h)
@@ -452,6 +470,10 @@ if (NOT CROSSTOOLS)
set(${FFTW_CLN}_FOUND FALSE)
set(${FFTW_CLNT}_FOUND FALSE)
if(${FFTW_CLN}_LIBRARIES)
if (NOT "${FFTW_MSG}" STREQUAL "")
set(FFTW_MSG "${FFTW_MSG}, ")
endif()
set(FFTW_MSG "${FFTW_MSG}${FFTW_CLN}")
set(${FFTW_CLN}_FOUND TRUE)
list(APPEND FFTW_LIBS "${FFTW_CLN}")
list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_LIBRARIES}")
@@ -475,7 +497,7 @@ if (NOT CROSSTOOLS)
endforeach()
endforeach()
if(FFTW_LIBS)
pip_module(fftw "${FFTW_LIBS}" "PIP FFTW support" "" "" "")
pip_module(fftw "${FFTW_LIBS}" "PIP FFTW support" "" "" " (${FFTW_MSG})")
endif()
endif()
@@ -570,7 +592,7 @@ if (NOT CROSSTOOLS)
if (NOT DEFINED ANDROID_PLATFORM)
if(microhttpd_FOUND AND curl_FOUND)
add_executable(pip_test "main.cpp")
target_link_libraries(pip_test pip pip_io_utils pip_client_server pip_http_server pip_http_client)
target_link_libraries(pip_test pip pip_io_utils pip_client_server pip_http_server pip_http_client pip_console)
if(sodium_FOUND)
add_executable(pip_cloud_test "main_picloud_test.cpp")
target_link_libraries(pip_cloud_test pip_cloud)

View File

@@ -189,8 +189,8 @@ void PIScreen::SystemConsole::print() {
for (int j = 0; j < dh; ++j) {
int k = j * dw + i;
Cell & c(cells[j + dy0][i + dx0]);
PRIVATE->chars[k].Char.UnicodeChar = 0;
PRIVATE->chars[k].Char.AsciiChar = c.symbol.toConsole1Byte();
PRIVATE->chars[k].Char.UnicodeChar = c.symbol.unicode16Code();
// PRIVATE->chars[k].Char.AsciiChar = c.symbol.toConsole1Byte();
PRIVATE->chars[k].Attributes = attributes(c);
}
// piCout << "draw" << dw << dh;
@@ -200,7 +200,7 @@ void PIScreen::SystemConsole::print() {
PRIVATE->srect.Top += dy0;
PRIVATE->srect.Right -= width - dx1 - 1;
PRIVATE->srect.Bottom -= height - dy1 - 1;
WriteConsoleOutput(PRIVATE->hOut, PRIVATE->chars.data(), PRIVATE->bs, PRIVATE->bc, &PRIVATE->srect);
WriteConsoleOutputW(PRIVATE->hOut, PRIVATE->chars.data(), PRIVATE->bs, PRIVATE->bc, &PRIVATE->srect);
#else
PIString s;
int si = 0, sj = 0;

View File

@@ -55,11 +55,12 @@ PIVariant PICodeInfo::getMemberAsVariant(const void * p, const char * class_name
PICodeInfo::__Storage__::__Storage__() {
classesInfo = new PIMap<PIConstChars, ClassInfo *>;
enumsInfo = new PIMap<PIConstChars, EnumInfo *>;
accessValueFunctions = new PIMap<PIConstChars, AccessValueFunction>;
accessTypeFunctions = new PIMap<PIConstChars, AccessTypeFunction>;
(*enumsInfo)[""] = new EnumInfo();
classesInfo = new PIMap<PIConstChars, ClassInfo *>;
enumsInfo = new PIMap<PIConstChars, EnumInfo *>;
accessValueFunctions = new PIMap<PIConstChars, AccessValueFunction>;
accessTypeFunctions = new PIMap<PIConstChars, AccessTypeFunction>;
accessOffsetFunctions = new PIMap<PIConstChars, AccessOffsetFunction>;
(*enumsInfo)[""] = new EnumInfo();
}
@@ -70,6 +71,7 @@ PICodeInfo::__Storage__::~__Storage__() {
piDeleteSafety(enumsInfo);
piDeleteSafety(accessValueFunctions);
piDeleteSafety(accessTypeFunctions);
piDeleteSafety(accessOffsetFunctions);
}

View File

@@ -58,6 +58,7 @@ typedef PIFlags<PICodeInfo::TypeFlag> TypeFlags;
typedef PIMap<PIString, PIString> MetaMap;
typedef PIByteArray (*AccessValueFunction)(const void *, const char *);
typedef const char * (*AccessTypeFunction)(const char *);
typedef int (*AccessOffsetFunction)(const char *);
//! \~english Type information
@@ -120,15 +121,15 @@ struct PIP_EXPORT FunctionInfo {
//! \~english Class or struct information
//! \~russian Информация о классе или структуре
struct PIP_EXPORT ClassInfo {
ClassInfo() { has_name = true; }
ClassInfo() { is_anonymous = false; }
//! \~english Custom PIMETA content
//! \~russian Произвольное содержимое PIMETA
MetaMap meta;
//! \~english Has name or not
//! \~russian Имеет или нет имя
bool has_name;
//! \~english Anonymous or not
//! \~russian Анонимный или нет
bool is_anonymous;
//! \~english Type
//! \~russian Тип
@@ -289,66 +290,77 @@ public:
PIMap<PIConstChars, PICodeInfo::EnumInfo *> * enumsInfo;
PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * accessValueFunctions;
PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * accessTypeFunctions;
PIMap<PIConstChars, PICodeInfo::AccessOffsetFunction> * accessOffsetFunctions;
private:
NO_COPY_CLASS(__Storage__)
};
class PIP_EXPORT __StorageAccess__ {
public:
//! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name
//! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::ClassInfo *> & classes() { return *(__Storage__::instance()->classesInfo); }
class PIP_EXPORT
__StorageAccess__{public:
//! \~english Getter for single storage of PICodeInfo::ClassInfo, access by name
//! \~russian Доступ к единому хранилищу PICodeInfo::ClassInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::ClassInfo *> & classes(){return *(__Storage__::instance()->classesInfo);
} // namespace PICodeInfo
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() { return *(__Storage__::instance()->enumsInfo); }
//! \~english Getter for single storage of PICodeInfo::EnumInfo, access by name
//! \~russian Доступ к единому хранилищу хранилище PICodeInfo::EnumInfo, доступ по имени
static const PIMap<PIConstChars, PICodeInfo::EnumInfo *> & enums() {
return *(__Storage__::instance()->enumsInfo);
}
static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueFunctions() {
return *(__Storage__::instance()->accessValueFunctions);
}
static const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> & accessValueFunctions() {
return *(__Storage__::instance()->accessValueFunctions);
}
static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() {
return *(__Storage__::instance()->accessTypeFunctions);
}
};
static const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> & accessTypeFunctions() {
return *(__Storage__::instance()->accessTypeFunctions);
}
static const PIMap<PIConstChars, PICodeInfo::AccessOffsetFunction> & accessOffsetFunctions() {
return *(__Storage__::instance()->accessOffsetFunctions);
}
}
;
#define PICODEINFO PICodeInfo::__StorageAccess__
class PIP_EXPORT ClassInfoInterface {
public:
const PIMap<PIConstChars, PICodeInfo::ClassInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::classes()") {
return __Storage__::instance()->classesInfo;
}
};
class PIP_EXPORT
ClassInfoInterface{public: const PIMap<PIConstChars, PICodeInfo::ClassInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::classes()"){
return __Storage__::instance() -> classesInfo;
}
}
;
static ClassInfoInterface classesInfo;
class PIP_EXPORT EnumsInfoInterface {
public:
const PIMap<PIConstChars, PICodeInfo::EnumInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::enums()") {
return __Storage__::instance()->enumsInfo;
}
};
class PIP_EXPORT
EnumsInfoInterface{public: const PIMap<PIConstChars, PICodeInfo::EnumInfo *> * operator->() const DEPRECATEDM("use PICODEINFO::enums()"){
return __Storage__::instance() -> enumsInfo;
}
}
;
static EnumsInfoInterface enumsInfo;
class PIP_EXPORT AccessValueFunctionInterface {
public:
const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * operator->() const DEPRECATEDM("use PICODEINFO::accessValueFunctions()") {
return __Storage__::instance()->accessValueFunctions;
}
};
class PIP_EXPORT AccessValueFunctionInterface{
public: const PIMap<PIConstChars, PICodeInfo::AccessValueFunction> * operator->()
const DEPRECATEDM("use PICODEINFO::accessValueFunctions()"){
return __Storage__::instance() -> accessValueFunctions;
}
}
;
static AccessValueFunctionInterface accessValueFunctions;
class PIP_EXPORT AccessTypeFunctionInterface {
public:
const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * operator->() const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()") {
return __Storage__::instance()->accessTypeFunctions;
}
};
class PIP_EXPORT AccessTypeFunctionInterface{
public: const PIMap<PIConstChars, PICodeInfo::AccessTypeFunction> * operator->()
const DEPRECATEDM("use PICODEINFO::accessTypeFunctions()"){
return __Storage__::instance() -> accessTypeFunctions;
}
}
;
static AccessTypeFunctionInterface accessTypeFunctions;

View File

@@ -19,6 +19,8 @@
#include "picodeparser.h"
#include "piliterals_string.h"
PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const {
PIStringList arg_vals;
@@ -92,10 +94,10 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
if (c->parent_scope)
piCout << "parent" << c->parent_scope->name;
piCout << "Functions:";
for (const auto & m: c->functions)
for (const auto & m: c->functions)
piCout << m.type << m.name << m.meta;
piCout << "Members:";
for (const auto & m: c->members)
for (const auto & m: c->members)
piCout << m.type << m.name << m.meta;
}
piCout << "\n\nDefines:";
@@ -108,7 +110,7 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) {
piCout << "\n\nEnums:";
for (const auto & c: enums) {
piCout << PIStringAscii("enum") << c.name << c.meta;
for (const auto & e: c.members)
for (const auto & e: c.members)
piCout << " " << e.name << '=' << e.value << e.meta;
}
piCout << "\n\nTypedefs:";
@@ -135,7 +137,7 @@ void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes)
piCout << PIStringAscii("enum") << c.name << c.members;
piCout << "\n\nTypedefs:";
for (const auto & c: typedefs)
piCout << PIStringAscii("typedef") << c;*/
piCout << PIStringAscii("typedef") << c;*/
}
@@ -328,7 +330,7 @@ void PICodeParser::clear() {
<< "a2"
<< "n2"
<< "a3"
<< "n3");
<< "n3");
}
@@ -454,7 +456,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
cur_namespace += pfc.takeCWord() + s_ns;
ccmn = pfc.takeRange('{', '}');
// piCout << "namespace" << cur_namespace;
parseClass(0, ccmn, true);
parseClass(nullptr, ccmn, true);
cur_namespace = prev_namespace;
continue;
}
@@ -483,8 +485,8 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
continue;
}
ccmn = pfc.left(dind) + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
pfc.remove(0, ccmn.size());
parseClass(0, ccmn, false);
pfc.remove(0, ccmn.size() - 2);
parseClass(nullptr, ccmn, false);
continue;
}
if (pfc.left(4) == s_enum) {
@@ -499,17 +501,59 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
meta << smeta;
}
// piCout << "pfc E" << cur_namespace << "," << tmp;
parseEnum(0, cur_namespace + tmp, pfc.takeRange('{', '}'), meta);
parseEnum(nullptr, cur_namespace + tmp, pfc.takeRange('{', '}'), meta);
pfc.takeSymbol();
continue;
}
if (pfc.left(7) == s_typedef) {
pfc.cutLeft(7);
typedefs << parseTypedef(pfc.takeLeft(pfc.find(';')));
if (typedefs.back().first.isEmpty())
typedefs.pop_back();
else
root_.typedefs << typedefs.back();
PIString typedef_type = pfc.takeCWord();
if (typedef_type == s_class || typedef_type == s_struct || typedef_type == s_union) {
int dind = pfc.find('{', 0), find = pfc.find(';', 0);
if (dind < 0 && find < 0) {
pfc.cutLeft(6);
continue;
}
if (dind < 0 || find < dind) {
pfc.cutLeft(find + 1);
continue;
}
PIString cname = pfc.left(dind);
ccmn = cname + s_bo + pfc.mid(dind).takeRange('{', '}') + s_bc;
pfc.remove(0, ccmn.size() - 3);
if (cname.trimmed().isEmpty()) {
cname = pfc.takeCWord();
ccmn.prepend(cname);
}
ccmn.prepend(typedef_type + " "_a);
parseClass(nullptr, ccmn, false);
} else if (typedef_type == s_enum) {
tmp = pfc.takeCWord();
pfc.trim();
MetaMap meta = maybeMeta(pfc);
if (tmp == s_class || tmp == s_struct) {
tmp = pfc.takeCWord();
pfc.trim();
MetaMap smeta = maybeMeta(pfc);
meta << smeta;
}
ccmn = pfc.takeRange('{', '}');
if (tmp.isEmpty()) {
tmp = pfc.takeCWord();
}
// piCout << "pfc E" << cur_namespace << "," << tmp;
parseEnum(nullptr, cur_namespace + tmp, ccmn, meta);
} else {
pfc.prepend(typedef_type);
}
PIString last = pfc.takeLeft(pfc.find(';')).trim();
if (last.isNotEmpty()) {
typedefs << parseTypedef(last);
if (typedefs.back().first.isEmpty())
typedefs.pop_back();
else
root_.typedefs << typedefs.back();
}
pfc.takeSymbol();
continue;
}
@@ -567,24 +611,23 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc)
Visibility vis = cur_def_vis;
cur_def_vis = (is_class ? Private : Public);
PIString cn = cd.mid(6).trim();
bool has_name = !cn.isEmpty();
bool is_anonymous = cn.isEmpty();
if (cn.isEmpty()) cn = PIStringAscii("<unnamed_") + PIString::fromNumber(anon_num++) + '>';
// piCout << "found " << typename_ << cn;
if (cn.isEmpty()) return nullptr;
Entity * e = new Entity();
e->meta = meta;
e->name = cur_namespace + cn;
e->type = typename_;
e->has_name = has_name;
e->parents = parents;
e->visibility = vis;
e->file = cur_file;
Entity * e = new Entity();
e->meta = meta;
e->name = cur_namespace + cn;
e->type = typename_;
e->is_anonymous = is_anonymous;
e->parents = parents;
e->visibility = vis;
e->file = cur_file;
entities << e;
return e;
}
void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) {
PICodeParser::Entity * PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace) {
static const PIString s_ns = PIStringAscii("::");
static const PIString s_public = PIStringAscii("public");
static const PIString s_protected = PIStringAscii("protected");
@@ -599,7 +642,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
static const PIString s_template = PIStringAscii("template");
Visibility prev_vis = cur_def_vis;
int dind = fc.find('{'), find = fc.find(';'), end = 0;
if (dind < 0 && find < 0) return;
if (dind < 0 && find < 0) return nullptr;
// piCout << "parse class <****\n" << fc << "\n****>";
Entity * ce = parent;
if (!is_namespace) {
@@ -608,7 +651,6 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
}
// piCout << "found class <****\n" << fc << "\n****>";
if (ce) {
if (parent) parent->children << ce;
ce->parent_scope = parent;
}
int ps = -1;
@@ -650,11 +692,29 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
fc.takeSymbol();
continue;
}
tmp = fc.takeLeft(fc.find('{'));
stmp = fc.takeRange('{', '}');
fc.takeSymbol();
stmp = cw + ' ' + tmp + '{' + stmp + '}';
parseClass(ce, stmp, false);
tmp = fc.takeLeft(fc.find('{')).trim();
stmp = fc.takeRange('{', '}');
stmp = cw + ' ' + tmp + '{' + stmp + '}';
auto new_entity = parseClass(ce, stmp, false);
// piCout << "!!! > \"" << fc << "\"";
PIStringList vars;
PIString var;
do {
var = fc.takeCWord();
if (var.isNotEmpty()) vars << var;
if (fc.takeSymbol() == ";") break;
} while (var.isNotEmpty());
if (new_entity) {
Member me;
me.visibility = cur_def_vis;
me.type = new_entity->name;
if (tmp.isEmpty() && vars.isEmpty()) vars = {""};
for (const auto & v: vars) {
me.name = v;
ce->members << me;
}
}
// piCout << "!!! <" << vars;
continue;
}
if (cw == s_enum) {
@@ -710,6 +770,7 @@ void PICodeParser::parseClass(Entity * parent, PIString & fc, bool is_namespace)
}
cur_def_vis = prev_vis;
cur_namespace = prev_namespace;
return ce;
}
@@ -766,7 +827,7 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc
PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) {
// piCout << "parse typedef" << fc;
// piCout << "parse typedef \"" << fc << "\"";
Typedef td;
fc.replaceAll('\t', ' ');
@@ -1197,7 +1258,7 @@ void PICodeParser::replaceMeta(PIString & dn) {
PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) {
for (auto * e: entities)
if (e->name == en) return e;
return 0;
return nullptr;
}

View File

@@ -100,7 +100,7 @@ public:
struct PIP_EXPORT Entity {
Entity() {
visibility = Global;
has_name = true;
is_anonymous = false;
size = 0;
parent_scope = 0;
}
@@ -110,10 +110,9 @@ public:
PIString file;
Visibility visibility;
int size;
bool has_name;
bool is_anonymous;
Entity * parent_scope;
PIVector<Entity *> parents;
PIVector<Entity *> children;
PIVector<Member> functions;
PIVector<Member> members;
PIVector<Typedef> typedefs;
@@ -164,7 +163,7 @@ private:
bool parseFileContent(PIString & fc, bool main);
bool parseDirective(PIString d);
Entity * parseClassDeclaration(const PIString & fc);
void parseClass(Entity * parent, PIString & fc, bool is_namespace);
Entity * parseClass(Entity * parent, PIString & fc, bool is_namespace);
MetaMap parseMeta(PIString & fc);
bool parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta);
Typedef parseTypedef(PIString fc);

View File

@@ -365,8 +365,8 @@ public:
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]);
insert(other.pim_index[0].key, other.pim_content[other.pim_index[0].index]);
insert(other.pim_index[1].key, other.pim_content[other.pim_index[1].index]);
return *this;
}
for (int i = 0; i < other.pim_index.size_s(); ++i) {

View File

@@ -12,7 +12,7 @@
*/
/*
PIP - Platform Independent Primitives
Base macros
Base macros
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
@@ -333,9 +333,10 @@ typedef long long ssize_t;
__PrivateInitializer__ __privateinitializer__;
# define PRIVATE_DEFINITION_START(c) struct c::__Private__ {
# define PRIVATE_DEFINITION_END(c) \
} \
; \
# define PRIVATE_DEFINITION_END_NO_INITIALIZE(c) \
} \
;
# define PRIVATE_DEFINITION_INITIALIZE(c) \
c::__PrivateInitializer__::__PrivateInitializer__() { \
p = new c::__Private__(); \
} \
@@ -350,6 +351,10 @@ typedef long long ssize_t;
p = new c::__Private__(); \
return *this; \
}
# define PRIVATE_DEFINITION_END(c) \
PRIVATE_DEFINITION_END_NO_INITIALIZE \
(c) PRIVATE_DEFINITION_INITIALIZE(c)
# define PRIVATE (__privateinitializer__.p)
# define PRIVATEWB __privateinitializer__.p

View File

@@ -938,7 +938,7 @@ PIString PIBinaryLog::constructFullPathDevice() const {
void PIBinaryLog::configureFromFullPathDevice(const PIString & full_path) {
const PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
const PIString p(pl[i]);
const PIString p(pl[i].trimmed());
switch (i) {
case 0: setLogDir(p); break;
case 1: setFilePrefix(p); break;

View File

@@ -181,7 +181,7 @@ void PICAN::configureFromFullPathDevice(const PIString & full_path) {
PIString p(pl[i]);
switch (i) {
case 0: setPath(p); break;
case 1: setCANID(p.toInt(16)); break;
case 1: setCANID(p.trimmed().toInt(16)); break;
default: break;
}
}

View File

@@ -1047,7 +1047,7 @@ void PIEthernet::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
bool mcast = false;
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
PIString p(pl[i].trimmed());
switch (i) {
case 0:
p = p.toLowerCase();

View File

@@ -1067,7 +1067,7 @@ PIString PIPeer::constructFullPathDevice() const {
void PIPeer::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
PIString p(pl[i].trimmed());
switch (i) {
case 0: changeName(p); break;
case 1: setTrustPeerName(p); break;

View File

@@ -983,7 +983,7 @@ void PISerial::configureFromFullPathDevice(const PIString & full_path) {
}
}
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
PIString p(pl[i].trimmed());
switch (i) {
case 0: setProperty("path", p); break;
case 1:

View File

@@ -182,7 +182,7 @@ void PISharedMemory::configureFromFullPathDevice(const PIString & full_path) {
initPrivate();
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
PIString p(pl[i].trimmed());
switch (i) {
case 0: setPath(p); break;
case 1: dsize = p.toInt(); break;

View File

@@ -187,7 +187,7 @@ PIString PISPI::constructFullPathDevice() const {
void PISPI::configureFromFullPathDevice(const PIString & full_path) {
PIStringList pl = full_path.split(":");
for (int i = 0; i < pl.size_s(); ++i) {
PIString p(pl[i]);
PIString p(pl[i].trimmed());
switch (i) {
case 0: setPath(p); break;
case 1: setSpeed(p.toInt()); break;

View File

@@ -225,17 +225,20 @@ bool PIVariant::operator==(const PIVariant & v) const {
PIVariant::Type PIVariant::typeFromName(const PIString & tname) {
PIString s = tname.trimmed().toLowerCase().replaceAll(" ", "");
if (s == "bool" || s == "boolean") return PIVariant::pivBool;
if (s == "char" || s == "sbyte") return PIVariant::pivChar;
if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword") return PIVariant::pivShort;
if (s == "int" || s == "signed" || s == "signedint") return PIVariant::pivInt;
if (s == "char" || s == "sbyte" || s == "int8_t") return PIVariant::pivChar;
if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword" || s == "int16_t")
return PIVariant::pivShort;
if (s == "int" || s == "signed" || s == "signedint" || s == "int32_t") return PIVariant::pivInt;
if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::pivInt;
if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword")
if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword" ||
s == "int64_t")
return PIVariant::pivLLong;
if (s == "uchar" || s == "byte") return PIVariant::pivUChar;
if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word") return PIVariant::pivUShort;
if (s == "uint" || s == "unsigned" || s == "unsignedint") return PIVariant::pivUInt;
if (s == "uchar" || s == "byte" || s == "uint8_t") return PIVariant::pivUChar;
if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word" || s == "uint16_t") return PIVariant::pivUShort;
if (s == "uint" || s == "unsigned" || s == "unsignedint" || s == "uint32_t") return PIVariant::pivUInt;
if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::pivUInt;
if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword") return PIVariant::pivULLong;
if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword" || s == "uint64_t")
return PIVariant::pivULLong;
if (s == "float") return PIVariant::pivFloat;
if (s == "double" || s == "real") return PIVariant::pivDouble;
if (s == "ldouble" || s == "longdouble") return PIVariant::pivLDouble;
@@ -709,6 +712,11 @@ int PIVariant::toInt() const {
ba >> r;
return (int)r.rgba;
}
case PIVariant::pivMathVector: {
PIMathVectord r;
ba >> r;
return r.size() > 0 ? r[0] : 0;
}
case PIVariant::pivCustom: return getAsValue<int>(*this);
default: break;
}
@@ -814,6 +822,11 @@ llong PIVariant::toLLong() const {
ba >> r;
return llong(r.selectedValue());
}
case PIVariant::pivMathVector: {
PIMathVectord r;
ba >> r;
return r.size() > 0 ? r[0] : 0L;
}
case PIVariant::pivCustom: return getAsValue<llong>(*this);
default: break;
}
@@ -919,6 +932,11 @@ float PIVariant::toFloat() const {
ba >> r;
return float(r.selectedValue());
}
case PIVariant::pivMathVector: {
PIMathVectord r;
ba >> r;
return r.size() > 0 ? r[0] : 0.f;
}
case PIVariant::pivCustom: return getAsValue<float>(*this);
default: break;
}
@@ -1024,6 +1042,11 @@ double PIVariant::toDouble() const {
ba >> r;
return double(r.selectedValue());
}
case PIVariant::pivMathVector: {
PIMathVectord r;
ba >> r;
return r.size() > 0 ? r[0] : 0.;
}
case PIVariant::pivCustom: return getAsValue<double>(*this);
default: break;
}
@@ -1129,6 +1152,11 @@ ldouble PIVariant::toLDouble() const {
ba >> r;
return ldouble(r.selectedValue());
}
case PIVariant::pivMathVector: {
PIMathVectord r;
ba >> r;
return r.size() > 0 ? r[0] : 0.;
}
case PIVariant::pivCustom: return getAsValue<float>(*this);
default: break;
}

464
main.cpp
View File

@@ -8,405 +8,91 @@
using namespace PICoutManipulators;
using namespace PIHTTP;
PIMathVectord data;
struct SN {
int _ii;
complexf _co;
PIIODevice::DeviceMode m;
};
struct S {
bool _b;
int _i;
float _f;
PIString str;
// SN _sn;
PIVector2D<bool> v2d;
PIByteArray ba;
PISystemTime st;
PINetworkAddress na;
PIPointd po;
PILined li;
PIRectd re;
};
template<>
PIJSON piSerializeJSON(const SN & v) {
PIJSON ret;
ret["_ii"] = piSerializeJSON(v._ii);
ret["_co"] = piSerializeJSON(v._co);
ret["m"] = piSerializeJSON(v.m);
return ret;
}
template<>
PIJSON piSerializeJSON(const S & v) {
PIJSON ret;
ret["_b"] = piSerializeJSON(v._b);
ret["_i"] = piSerializeJSON(v._i);
ret["_f"] = piSerializeJSON(v._f);
ret["str"] = piSerializeJSON(v.str);
// ret["_sn"] = piSerializeJSON(v._sn);
ret["v2d"] = piSerializeJSON(v.v2d);
ret["ba"] = piSerializeJSON(v.ba);
ret["st"] = piSerializeJSON(v.st);
ret["na"] = piSerializeJSON(v.na);
ret["po"] = piSerializeJSON(v.po);
ret["li"] = piSerializeJSON(v.li);
ret["re"] = piSerializeJSON(v.re);
return ret;
void _sfplot(const PIMathVectord & sf, PIString * str, const int lines, const int length) {
int offset = (data.size() - length) / 2 / 2;
double max_sf = 0;
for (int i = 0; i < length * 2; i++) {
if (sf[offset + i] > max_sf) {
max_sf = sf[offset + i];
}
}
static PIVector2D<uchar> grid;
grid.clear();
grid.resize(lines * 2, length * 2);
// clang-format off
static const PIChar dots[16] = {
PIChar::fromUTF8(" "), PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""),
PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""),
PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""),
PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""), PIChar::fromUTF8(""),
};
// clang-format on
memset(grid.data(), 0, grid.size());
for (int c = 0; c < grid.cols(); c++) {
double rind = piClampi(piRound(sf[offset + c] / max_sf * (grid.rows() - 1)), 0, grid.rows() - 1);
grid.element(rind, c) = 1;
}
union helper {
uint index = 0;
struct {
uint tl: 1;
uint tr: 1;
uint bl: 1;
uint br: 1;
};
};
for (int i = 0; i < lines; i++) {
str[i].resize(length);
}
helper h;
for (int l = 0; l < lines; l++) {
for (int c = 0; c < length; c++) {
int l2 = l + l;
int c2 = c + c;
h.bl = grid.element(l2, c2);
h.br = grid.element(l2, c2 + 1);
h.tl = grid.element(l2 + 1, c2);
h.tr = grid.element(l2 + 1, c2 + 1);
// piCout << h.index;
str[lines - 1 - l][c] = dots[h.index];
}
}
}
template<>
void piDeserializeJSON(SN & v, const PIJSON & js) {
v = {};
piDeserializeJSON(v._ii, js["_ii"]);
piDeserializeJSON(v._co, js["_co"]);
piDeserializeJSON(v.m, js["m"]);
}
template<>
void piDeserializeJSON(S & v, const PIJSON & js) {
v = {};
piDeserializeJSON(v._b, js["_b"]);
piDeserializeJSON(v._i, js["_i"]);
piDeserializeJSON(v._f, js["_f"]);
piDeserializeJSON(v.str, js["str"]);
// piDeserializeJSON(v._sn, js["_sn"]);
piDeserializeJSON(v.v2d, js["v2d"]);
piDeserializeJSON(v.ba, js["ba"]);
piDeserializeJSON(v.st, js["st"]);
piDeserializeJSON(v.na, js["na"]);
piDeserializeJSON(v.po, js["po"]);
piDeserializeJSON(v.li, js["li"]);
piDeserializeJSON(v.re, js["re"]);
}
PIKbdListener kbd;
TileSimple * test_tile;
PIScreen screen;
PIMathVectord asf;
int main(int argc, char * argv[]) {
if (argc < 2) return 0;
PIFile f(argv[1], PIIODevice::ReadOnly);
piCout << "read" << f.path();
auto fc = f.readAll();
piCout << fc.size();
if (!fc.isEmpty()) piCout << PIString::fromUTF8(fc.resized(32));
return 0;
test_tile = new TileSimple();
screen.rootTile()->addTile(test_tile);
screen.rootTile()->addTile(new TilePICout());
PITimer _t;
PIString str[9];
asf.resize(80);
_t.start(20_Hz, [&str] {
static double t = 0;
t += 0.1;
for (uint i = 0; i < asf.size(); ++i)
asf[i] = 1. + sin(t + 2. * i * M_2PI / asf.size());
_sfplot(asf, str, 9, 28);
PIHTTPServer server;
server.listen({"127.0.0.1:7777"});
// server.setBasicAuthRealm("pip");
// server.setBasicAuthEnabled(true);
// server.setBasicAuthCallback([](const PIString & u, const PIString & p) -> bool {
// piCout << "basic auth" << u << p;
// return (u == "u" && p == "p");
auto reg = [&server](const PIString & path) {
server.registerPath(path, Method::Get, [path](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable {
piCout << "\nserver rec:\n\tpath: %1\n\t url: %2\n\t args: %3\n\tQ args: %4\n\tP args: %5"_a.arg(path)
.arg(msg.path())
.arg(piStringify(msg.arguments()))
.arg(piStringify(msg.queryArguments()))
.arg(piStringify(msg.pathArguments()));
return MessageMutable().setCode(Code::Accepted);
});
};
// });
reg(" /*/a/get ");
reg(" /*/{ID}/get ");
reg(" /*/*/get ");
reg(" /*/*_b/get ");
reg("/api/{ID}/get");
reg("/api/1/get");
// reg("/api/1/bort{bortID}/get");
// reg("/api/**");
// reg("/api/1/bort2/get");
// reg("/api/**/bort2/get");
/*server.registerPath("api/{ID}/bort{bortID}/get", Method::Get, [](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable {
piCout << "server rec:\n\tpath: %1\n\targs: %2\n\tQ args: %3\n\tP args: %4\n"_a.arg(msg.path())
.arg(piStringify(msg.arguments()))
.arg(piStringify(msg.queryArguments()))
.arg(piStringify(msg.pathArguments()));
return MessageMutable().setCode(Code::Accepted);
screen.lock();
test_tile->content.resize(9);
for (int i = 0; i < 9; i++) {
test_tile->content[i].first = str[i];
}
screen.unlock();
piCout << "Время: "_u8 << t;
});
server.registerPath("sendMessage", Method::Post, [](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable {
return MessageMutable().setCode(Code::Accepted);
});
server.registerUnhandled([](const PIHTTP::MessageConst & msg) -> PIHTTP::MessageMutable {
PIHTTP::MessageMutable ret;
piCout << "server rec:\n\tpath: %1\n\tmethod: %2\n\targs: %3\n\theaders: %4\n\tbody: %5\n"_a.arg(msg.path())
.arg(PIHTTP::methodName(msg.method()))
.arg(piStringify(msg.arguments()))
.arg(PIStringList(msg.headers().map<PIString>([](PIString k, PIString v) { return k + " = " + v; })).join("\n\t\t "))
.arg(PIString::fromUTF8(msg.body()));
ret.setCode(PIHTTP::Code::BadRequest);
ret.setBody(PIByteArray::fromAscii("hello client! 0123456789"));
return ret;
});*/
kbd.enableExitCapture('Q');
screen.enableExitCapture();
WAIT_FOR_EXIT;
return 0;
// PIRegularExpression pire("привет"_u8, PIRegularExpression::CaseInsensitive);
// PIString subj = "the dog ПриВет sat on the cat"_u8;
// PIRegularExpression pire("^(?<date>\\d\\d)/(?<month>\\d\\d)/(?<year>\\d\\d\\d\\d)$"_u8);
// PIString subj = "08/12/1985"_u8;
PIString pat = "*.Exe";
PIRegularExpression re_g = PIRegularExpression::fromGlob(pat, PIRegularExpression::CaseInsensitive);
PIRegularExpression re_p = PIRegularExpression::fromPOSIX(pat, PIRegularExpression::CaseInsensitive);
PIStringList files = {
"(Audio) 20250318-0852-16.8641941.m4a",
"dxwebsetup.exe",
"Firefox Installer.exe",
"LTA8092XS8_R8.pdf",
"SteamSetup.exe",
"TBT_1.41.1325.0.exe",
};
piCout << " src pat" << pat.quoted();
piCout << " Glob pat" << re_g.pattern().quoted();
piCout << "POSIX pat" << re_p.pattern().quoted();
piCout << "\nG P File";
for (auto f: files) {
piCout << (re_g.match(f) ? 1 : 0) << (re_p.match(f) ? 1 : 0) << f;
}
// return 0;
PIRegularExpression pire("(?:\\/\\/\\s*)?.*\\n?(?:\\bfunction\\b)\\s*(?<name>\\b\\w+\\b)\\s*(?:\\((?<args>[^;()]*?)\\))",
PIRegularExpression::Multiline);
PIString subj = PIString::fromUTF8(PIFile::readAll("telegram.qs"));
piCout << "Pattern:" << pire.pattern();
piCout << "Valid:" << pire.isValid();
piCout << "Error at" << pire.errorPosition() << ":" << pire.errorString();
piCout << "Groups count:" << pire.captureGroupsCount();
piCout << "Named groups:" << pire.captureGroupNames();
piCout << "";
auto mr = pire.matchIterator(subj);
auto pire2 = pire;
while (mr.next()) {
// piCout << "Subject" << subj;
piCout << "Matched:" << mr.hasMatch();
piCout << "By number";
for (int i = 0; i <= pire.captureGroupsCount(); ++i)
piCout << i << "=" << mr.matchedString(i).trimmed();
piCout << "By name";
for (auto g: pire.captureGroupNames())
piCout << g.quoted() << "=" << mr.matchedString(g);
piCout << "";
}
piCout << "!!!!!!!!!!!!!!!!!";
pire.match("vfsmndvbjbdlgdvb gdgf");
pire.match(subj);
{
PIVector<complexf> vec;
vec << complexf{0.1, 0.2} << complexf{-1, 0.5};
auto js = PIJSON::serialize(vec);
piCout << vec;
piCout << js;
piCout << PIJSON::deserialize<typeof(vec)>(js);
}
return 0;
/*PICodeParser parser;
parser.parseFile("c:/work/shstk/pip/test_header.h", false);
for (const auto * e: parser.entities) {
piCout << e->type << e->name << "{";
for (const auto & m: e->members) {
piCout << " " << m.type << m.name;
}
piCout << "}";
}
return 0;*/
// PIJSON j = piSerializeJSON(s);
// piDeserializeJSON(s, j);
PIVector<complexf> vec;
vec << complexf{0.1, 0.2} << complexf{-1, 0.5};
auto js = PIJSON::serialize(vec);
piCout << vec;
piCout << js;
piCout << PIJSON::deserialize<typeof(vec)>(js);
/*PIVector<S> s;
s << S{false, 0, 0.1} << S{true, 1, -10.1};
PIMap<int, S> m;
m[1] = S{false, 0, 0.15};
m[2] = S{true, 1, -10.1};
// m[1]._sn._co = {3, 4};
PIJSON j = piSerializeJSON(m);
piCout << j;
piDeserializeJSON(m, j);
piCout << m[1]._f;*/
// piCout << m[1]._sn._co;
/*PIVector<int> v({-1, 0, 10, 200});
PIMap<int, float> m({
{-1, -0.1 },
{0, 0.1 },
{100, 200.2}
});
piCout << v;
piCout << piSerializeJSON(v);
piDeserializeJSON(v, piSerializeJSON(v));
piCout << v;
piCout << m;
piDeserializeJSON(m, piSerializeJSON(m));
piCout << piSerializeJSON(m);*/
return 0;
/*auto src = PIByteArray::fromAscii("The quick brown fox jumps over the lazy dog");
auto key = PIByteArray::fromAscii("key");
PIStringList tnl;
int max_size = 0;
for (int t = 0; t < (int)PIDigest::Type::C ount; ++t) {
tnl << PIDigest::typeName((PIDigest::Type)t);
max_size = piMaxi(max_size, tnl.back().size_s());
}
PIByteArray hs;
piCout << PIString::fromAscii(src);
for (int t = 0; t < (int)PIDigest::Type::Count; ++t) {
hs = PIDigest::calculate(src, (PIDigest::Type)t);
piCout << tnl[t].expandLeftTo(max_size, ' ') << "->" << hs.toHex();
}
for (int t = 0; t < (int)PIDigest::Type::Count; ++t) {
const int bench_count = 100000;
PITimeMeasurer tm;
piForTimes(bench_count) {
hs = PIDigest::calculate(src, (PIDigest::Type)t);
}
auto el = tm.elapsed();
piCout << tnl[t].expandLeftTo(max_size, ' ') << "time" << el.toMilliseconds();
}
// src.clear();
// crypto_hash_sha512(sout.data(), src.data(), src.size());
// piCout << "sod:" << sout.toHex();
// piCout << "512:" << sha5xx(src, initial_512, 64).toHex();
return 0;*/
/*PIHTTP::MessageMutable req;
req.setBody(PIByteArray::fromAscii("hello server!")).addArgument("a0", "val.0").addArgument("a~r1", "знач,1"_u8);
auto * c = PIHTTPClient::create("http://u:p@127.0.0.1:7777/api", PIHTTP::Method::Get, req);
c->onFinish([](PIHTTP::MessageConst msg) {
piCout << "client rec:\n\tpath: %1\n\tmethod: %2\n\targs: %3\n\theaders: %4\n\tbody: %5\n"_a.arg(msg.path())
.arg(PIHTTP::methodName(msg.method()))
.arg(piStringify(msg.arguments()))
.arg(
PIStringList(msg.headers().map<PIString>([](PIString k, PIString v) { return k + " = " + v; })).join("\n\t\t
")) .arg(PIString::fromUTF8(msg.body()));
})
->onError([c](PIHTTP::MessageConst r) {
piCout << "error" << (int)r.code();
piCout << "msg" << c->lastError();
})
->onAbort([c](PIHTTP::MessageConst r) {
piCout << "abort" << (int)r.code();
piCout << "msg" << c->lastError();
})
->start();*/
auto * c = PIHTTPClient::create(
PIString("127.0.0.1:7777/%1").arg("sendMessag"),
Method::Post,
MessageMutable().addHeader(Header::ContentType, "application/json").setBody(PIByteArray::fromAscii("{hello}")));
c->onFinish([](const PIHTTP::MessageConst & msg) { piCout << "message finish" << (int)msg.code() << PIString::fromUTF8(msg.body()); })
->onError([c](const PIHTTP::MessageConst & msg) { piCout << "message error" << c->lastError(); })
->onAbort([c](const PIHTTP::MessageConst & msg) { piCout << "aborted"; })
->start();
piMSleep(1000);
// CurlThreadPool::instance()->destroy();
// kbd.enableExitCapture();
// WAIT_FOR_EXIT
// kbd.stopAndWait();
// server.stop();
c->abort();
piMSleep(10);
return 0;
// piCout << PIString::readableSize(PISystemMonitor::usedRAM());
/*PIVector<int> vi;
piForTimes(10) {
piSleep(2.);
vi.enlarge(1000000);
piCout << "now" << vi.size() << vi.capacity();
}
piSleep(5.);*/
/*kbd.enableExitCapture();
PIHTTPServer server;
server.setFavicon(PIFile::readAll("logo.png", false));
// server.setOption(MicrohttpdServer::Option::HTTPSEnabled, true);
server.listen({"127.0.0.1", 7777});
// server.listen({"192.168.1.10", 7778});
server.registerPath("/", MicrohttpdServer::Method::Get, [](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply ret;
ret.setBody(PIByteArray::fromAscii(pageTitle));
return ret;
});
server.registerPath("/html", MicrohttpdServer::Method::Get, [](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply ret;
ret.setBody("<!DOCTYPE html><html><body><p>arg=%1</p></body></html>"_a.arg(r.args.value("a0")).toUTF8());
return ret;
});
server.registerPath("/api", MicrohttpdServer::Method::Put, [](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply ret;
ret.setBody(PIByteArray::fromAscii("<!DOCTYPE html><html><body>API</body></html>"));
return ret;
});
server.registerPath("/api/", MicrohttpdServer::Method::Post, [](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply ret;
ret.setBody("<!DOCTYPE html><html><body>API etry %1</body></html>"_a.arg(r.path).toUTF8());
ret.setCode(405);
return ret;
});
server.registerUnhandled([](const MicrohttpdServer::Request & r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply ret;
ret.setBody("<!DOCTYPE html><html><body>Unknown</body></html>"_a.arg(r.path).toUTF8());
ret.setCode(404);
return ret;
});*/
/*server.setRequestCallback([](MicrohttpdServer::Request r) -> MicrohttpdServer::Reply {
MicrohttpdServer::Reply rep;
piCout << "request" << r.path;
piCout << " header" << r.headers;
piCout << " args" << r.args;
piCout << " body" << r.body;
piCout << "";
rep.setBody(PIByteArray::fromAscii("[{\"value1\": true, \"value2\": \"ыекштп\"}]"));
return rep;
});*/
/*piCout << "start" << server.isListen();
WAIT_FOR_EXIT
server.stop();*/
screen.stopAndWait();
return 0;
}

View File

@@ -46,8 +46,15 @@ const char help_string[] = "-M (Metainfo)\n"
"with simple << and >> operators.\n"
"If PIMETA(no-stream) presence, then class or struct ignored.\n"
"\n"
"-J (JSON serialization)\n"
"Generate serialize/deserialize methods for classes and structures.\n"
"These methods uses by PIJSON::serialize(T v) and PIJSON::deserialize(json)\n"
"allow automatic conversion to/from PIJSON. Use member name as key.\n"
"Member can be skipped by providing PIMETA(id=-).\n"
"If PIMETA(no-json) presence, then class or struct ignored.\n"
"\n"
"-G (Getter functions)\n"
"Generate anonymous access methods for member typenames and values.\n"
"Generate anonymous access methods for member typenames, values and offsets.\n"
"Every class or struct member typename can be obtained with:\n"
"const char * getMemberType(const char * class_name, const char * member_name)\n"
"Member value can be obtained with:\n"
@@ -55,6 +62,7 @@ const char help_string[] = "-M (Metainfo)\n"
"where \"p\" - class or struct pointer, and returns serialized value.\n"
"PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name)\n"
"where \"p\" - class or struct pointer, and returns value as registered PIVariant.\n"
"If PIMETA(no-getter) presence, then class or struct ignored.\n"
"";
@@ -126,3 +134,8 @@ PIString toCName(const PIString & s) {
ret.replaceAll("__", "_");
return ret;
}
PICodeParser::Entity * findEntity(Runtime & rt, const PIString & type) {
return rt.parser.findEntityByName(type);
}

View File

@@ -35,5 +35,6 @@ void usage();
void help();
PIString toCName(const PIString & s);
PICodeParser::Entity * findEntity(Runtime & rt, const PIString & type);
#endif

View File

@@ -22,27 +22,100 @@
#include "stream.h"
void writeGetterTypeMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PISet<int> used_id;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeGetterTypeMembers(rt, type, var_prefix + m.name);
continue;
}
}
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) return \"" << m.type;
// if (m.isBitfield()) rt.ts << ":" << m.bits;
rt.ts << "\";\n";
}
}
void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PISet<int> used_id;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeGetterValueMembers(rt, type, var_prefix + m.name);
continue;
}
}
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) {";
if (m.isBitfield()) {
rt.ts << "ret = piSerialize(static_cast<" << m.type << ">(o->" << var_prefix << m.name << "));";
} else
rt.ts << "serialize(ret, o->" << var_prefix << m.name << ");";
rt.ts << " return ret;}\n";
}
}
void writeGetterOffsetMembers(Runtime & rt, const PICodeParser::Entity * e, PIString entity_name, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PISet<int> used_id;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || !m.dims.isEmpty() || m.isBitfield() || (m.visibility != PICodeParser::Public)) continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeGetterOffsetMembers(rt, type, entity_name, var_prefix + m.name);
continue;
}
}
rt.ts << "\tif (strcmp(name, \"" << var_prefix << m.name << "\") == 0) ";
rt.ts << "return PICODEINFO_OFFSET(" << entity_name << ", " << var_prefix << m.name << ");\n";
}
}
void makeGetterType(Runtime & rt, const PICodeParser::Entity * e) {
if (!needClassStream(e)) return;
if (!needClassGetter(e)) return;
rt.ts << "\nconst char * getterType" << toCName(e->name) << "(const char * name) {\n";
rt.ts << "\tif (!name) return \"\";\n";
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
rt.ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) return \"" << m.type << "\";\n";
}
writeGetterTypeMembers(rt, e);
rt.ts << "\treturn \"\";\n}\n";
}
void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e) {
if (!needClassStream(e)) return;
if (!needClassGetter(e)) return;
rt.ts << "\nPIByteArray getterValue" << toCName(e->name) << "(const void * p, const char * name) {\n";
rt.ts << "\tPIByteArray ret;\n";
rt.ts << "\tif (!p || !name) return ret;\n";
rt.ts << "\t" << e->name << " * o = (" << e->name << "*)p;\n";
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
rt.ts << "\tif (strcmp(name, \"" << m.name << "\") == 0) {serialize(ret, o->" << m.name << "); return ret;}\n";
}
writeGetterValueMembers(rt, e);
rt.ts << "\treturn ret;\n}\n";
}
void makeGetterOffset(Runtime & rt, const PICodeParser::Entity * e) {
if (!needClassGetter(e)) return;
rt.ts << "\nint getterOffset" << toCName(e->name) << "(const char * name) {\n";
rt.ts << "\tif (!name) return 0;\n";
writeGetterOffsetMembers(rt, e, e->name);
rt.ts << "\treturn 0;\n}\n";
}
bool needClassGetter(const PICodeParser::Entity * e) {
if (e->meta.contains("no-getter")) return false;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue;
if (m.attributes[PICodeParser::Static]) continue;
return true;
}
return false;
}

View File

@@ -22,7 +22,12 @@
#include "common.h"
void writeGetterTypeMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
void writeGetterValueMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
void writeGetterOffsetMembers(Runtime & rt, const PICodeParser::Entity * e, PIString entity_name, PIString var_prefix = {});
void makeGetterType(Runtime & rt, const PICodeParser::Entity * e);
void makeGetterValue(Runtime & rt, const PICodeParser::Entity * e);
void makeGetterOffset(Runtime & rt, const PICodeParser::Entity * e);
bool needClassGetter(const PICodeParser::Entity * e);
#endif

View File

@@ -22,7 +22,8 @@
#include "pitranslator.h"
bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) {
bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -30,12 +31,19 @@ bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) {
}
bool is_union = e->type == "union";
for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue;
if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue;
// if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeClassJSONMembersOut(rt, type, var_prefix + m.name);
continue;
}
}
if (m.dims.isEmpty()) {
rt.ts << "\tret[\"" << m.name << "\"] = piSerializeJSON(v." << m.name << ");\n";
rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(v." << var_prefix << m.name << ");\n";
} else {
PIString ptype = m.type.left(m.type.find('[')).trim();
PIString size = m.dims[0];
@@ -43,21 +51,22 @@ bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e) {
size += " * ";
size += m.dims[i];
}
rt.ts << "\tret[\"" << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name
<< "), " << size << "));\n";
rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v."
<< var_prefix << m.name << "), " << size << "));\n";
}
if (is_union) break;
}
if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
/*for (const PICodeParser::Entity * ce: e->children) {
if (!ce->is_anonymous) continue;
if (!writeClassJSONMembersOut(rt, ce)) return false;
}
}*/
return true;
}
bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) {
bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -66,12 +75,19 @@ bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) {
bool is_union = e->type == "union";
PISet<int> used_id;
for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue;
if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeClassJSONMembersIn(rt, type, var_prefix + m.name);
continue;
}
}
// if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
if (m.dims.isEmpty()) {
rt.ts << "\tpiDeserializeJSON(v." << m.name << ", js[\"" << m.name << "\"]);\n";
rt.ts << "\tpiDeserializeJSON(v." << var_prefix << m.name << ", js[\"" << var_prefix << m.name << "\"]);\n";
} else {
PIString ptype = m.type.left(m.type.find('[')).trim();
PIString size = m.dims[0];
@@ -80,19 +96,19 @@ bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e) {
size += m.dims[i];
}
rt.ts << "\t{\n\t\tPIVector<" << ptype << " > d;\n";
rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << m.name << "\"]);\n";
rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << var_prefix << m.name << "\"]);\n";
rt.ts << "\t\tint cnt = piMini(d.size_s(), " << size << ");\n";
rt.ts << "\t\tfor (int i = 0; i < cnt; ++i)\n";
rt.ts << "\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n";
rt.ts << "\t\t\t((" << ptype << " *)(v." << var_prefix << m.name << "))[i] = d[i];\n";
rt.ts << "\t}\n";
}
if (is_union) break;
}
if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
/*for (const PICodeParser::Entity * ce: e->children) {
if (!ce->is_anonymous) continue;
if (!writeClassJSONMembersIn(rt, ce)) return false;
}
}*/
return true;
}

View File

@@ -22,8 +22,8 @@
#include "common.h"
bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e);
bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e);
bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
bool needClassJSON(const PICodeParser::Entity * e);
bool makeClassJSON(Runtime & rt, const PICodeParser::Entity * e);

View File

@@ -66,11 +66,15 @@ bool writeModel(PICodeParser & parser,
if (meta || enums || getters) {
if (getters) {
ts << "\n\n// Getter funtions\n";
ts << "\n#define PICODEINFO_OFFSET(type, member) reinterpret_cast<size_t>(&reinterpret_cast<const char &>((((type "
"*)nullptr)->member)))\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI")) continue;
if (e->is_anonymous || e->name.startsWith("_PI")) continue;
makeGetterType(rt, e);
makeGetterValue(rt, e);
makeGetterOffset(rt, e);
}
ts << "\n#undef PICODEINFO_OFFSET\n";
}
ts << "\n\n// Metainformation\n\n__ClassInfo_" << defname << "_Initializer__::__ClassInfo_" << defname << "_Initializer__() {\n";
ts << "\tstatic __ClassInfo_" << defname << "_Initializer__::Content content;\n";
@@ -83,6 +87,7 @@ bool writeModel(PICodeParser & parser,
if (getters) {
ts << "\tauto & ci_avf(*ci_ins->accessValueFunctions);\n";
ts << "\tauto & ci_atf(*ci_ins->accessTypeFunctions);\n";
ts << "\tauto & ci_aof(*ci_ins->accessOffsetFunctions);\n";
}
if (meta) {
@@ -95,7 +100,7 @@ bool writeModel(PICodeParser & parser,
if (meta) {
ts << "\n\n// Classes\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (e->name.startsWith("_PI")) continue;
if (e->name.startsWith("_PI") || e->is_anonymous) continue;
makeClassInfo(rt, e);
}
}
@@ -108,9 +113,11 @@ bool writeModel(PICodeParser & parser,
ts << "\n// Getters\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (!needClassStream(e)) continue;
if (!e->has_name || e->name.startsWith("_PI")) continue;
ts << "\tci_avf[\"" << e->name << "\"] = getterValue" << toCName(e->name) << ";\n";
ts << "\tci_atf[\"" << e->name << "\"] = getterType" << toCName(e->name) << ";\n";
if (e->is_anonymous || e->name.startsWith("_PI")) continue;
auto cname = toCName(e->name);
ts << "\tci_avf[\"" << e->name << "\"] = getterValue" << cname << ";\n";
ts << "\tci_atf[\"" << e->name << "\"] = getterType" << cname << ";\n";
ts << "\tci_aof[\"" << e->name << "\"] = getterOffset" << cname << ";\n";
}
}
ts << "}\n\n";
@@ -121,11 +128,12 @@ bool writeModel(PICodeParser & parser,
if (getters) {
ts << "\tauto & ci_avf(*ci_ins->accessValueFunctions);\n";
ts << "\tauto & ci_atf(*ci_ins->accessTypeFunctions);\n";
ts << "\tauto & ci_aof(*ci_ins->accessOffsetFunctions);\n";
}
if (meta) {
ts << "\n// Classes clean\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (e->name.startsWith("_PI")) continue;
if (e->name.startsWith("_PI") || e->is_anonymous) continue;
ts << "\tpiDeleteSafety(ci_ci[\"" << e->name << "\"]);\n";
ts << "\tci_ins->classesInfo->remove(\"" << e->name << "\");\n";
}
@@ -143,9 +151,10 @@ bool writeModel(PICodeParser & parser,
ts << "\n// Getters clean\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (!needClassStream(e)) continue;
if (!e->has_name || e->name.startsWith("_PI")) continue;
if (e->is_anonymous || e->name.startsWith("_PI")) continue;
ts << "\tci_avf.remove(\"" << e->name << "\");\n";
ts << "\tci_atf.remove(\"" << e->name << "\");\n";
ts << "\tci_aof.remove(\"" << e->name << "\");\n";
}
}
ts << "}\n";
@@ -173,7 +182,7 @@ bool writeModel(PICodeParser & parser,
if (streams) {
ts << "\n\n// Stream operators\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI") ||
if (e->is_anonymous || e->name.startsWith("_PI") ||
!(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public))
continue;
if (!makeClassStream(rt, e)) return false;
@@ -182,7 +191,7 @@ bool writeModel(PICodeParser & parser,
if (json) {
ts << "\n\n// JSON serialization\n";
for (const PICodeParser::Entity * e: parser.entities) {
if (!e->has_name || e->name.startsWith("_PI") ||
if (e->is_anonymous || e->name.startsWith("_PI") ||
!(e->visibility == PICodeParser::Global || e->visibility == PICodeParser::Public))
continue;
if (!makeClassJSON(rt, e)) return false;

View File

@@ -20,27 +20,17 @@
#include "metainfo.h"
void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) {
rt.ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n";
rt.ts << "\tci->type = \"" << e->type << "\";\n";
rt.ts << "\tci->name = \"" << e->name << "\";\n";
rt.ts << "\tci->has_name = " << (e->has_name ? "true" : "false") << ";\n";
if (!e->meta.isEmpty()) {
auto i = e->meta.makeIterator();
while (i.next())
rt.ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n";
}
rt.ts << "\tci_ci[ci->name] = ci;\n";
if (e->parent_scope) {
rt.ts << "\tpci = "
<< "ci_ci.value(\"" << e->parent_scope->name << "\", 0);\n";
rt.ts << "\tif (pci) pci->children_info << ci;\n";
}
for (const PICodeParser::Entity * p: e->parents)
rt.ts << "\tci->parents << \"" << p->name << "\";\n";
if (!e->members.isEmpty()) rt.ts << "\n\tTypeInfo ti;\n";
void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
for (const PICodeParser::Member & m: e->members) {
rt.ts << "\tti = TypeInfo(\"" << m.name << "\", \"" << m.type << "\"";
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
writeClassInfoMembers(rt, type, var_prefix + m.name);
continue;
}
}
rt.ts << "\tti = TypeInfo(\"" << var_prefix << m.name << "\", \"" << m.type << "\"";
if (m.attributes != 0) {
bool fir = true;
rt.ts << ", ";
@@ -97,6 +87,29 @@ void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) {
}
rt.ts << "\tci->variables << ti;\n";
}
}
void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e) {
rt.ts << "\n\t{\n\tClassInfo * ci = new ClassInfo();\n";
rt.ts << "\tci->type = \"" << e->type << "\";\n";
rt.ts << "\tci->name = \"" << e->name << "\";\n";
// rt.ts << "\tci->is_anonymous = " << (e->is_anonymous ? "true" : "false") << ";\n";
if (!e->meta.isEmpty()) {
auto i = e->meta.makeIterator();
while (i.next())
rt.ts << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n";
}
rt.ts << "\tci_ci[ci->name] = ci;\n";
if (e->parent_scope) {
rt.ts << "\tpci = "
<< "ci_ci.value(\"" << e->parent_scope->name << "\", 0);\n";
rt.ts << "\tif (pci) pci->children_info << ci;\n";
}
for (const PICodeParser::Entity * p: e->parents)
rt.ts << "\tci->parents << \"" << p->name << "\";\n";
if (!e->members.isEmpty()) rt.ts << "\n\tTypeInfo ti;\n";
writeClassInfoMembers(rt, e);
PIString arg;
bool has_fi = false;
for (const PICodeParser::Member & m: e->functions) {

View File

@@ -22,6 +22,7 @@
#include "common.h"
void writeClassInfoMembers(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix = {});
void makeClassInfo(Runtime & rt, const PICodeParser::Entity * e);
#endif

View File

@@ -22,7 +22,8 @@
#include "pitranslator.h"
bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple) {
bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -31,9 +32,16 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in
bool is_union = e->type == "union";
PISet<int> used_id;
for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue;
if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
if (!writeClassStreamMembersOut(rt, type, cnt, simple, var_prefix + m.name)) return false;
continue;
}
}
++cnt;
if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
if (used_id[cnt]) {
@@ -44,11 +52,11 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in
if (simple) {
rt.ts << "\ts << ";
if (rt.parser.isEnum(m.type)) rt.ts << "(int)";
rt.ts << "v." << m.name << ";\n";
rt.ts << "v." << var_prefix << m.name << ";\n";
} else {
rt.ts << "\tcs.add(" << cnt << ", ";
if (rt.parser.isEnum(m.type)) rt.ts << "(int)";
rt.ts << "v." << m.name << ");\n";
rt.ts << "v." << var_prefix << m.name << ");\n";
}
} else {
PIString ptype = m.type.left(m.type.find('[')).trim();
@@ -59,24 +67,22 @@ bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, in
}
if (simple) {
rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n";
rt.ts << "\t\ts << ((const " << ptype << " *)(v." << m.name << "))[i];\n";
rt.ts << "\t\ts << ((const " << ptype << " *)(" << "v." << var_prefix << m.name << "))[i];\n";
} else {
rt.ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(v." << m.name << "), ";
rt.ts << "\tcs << cs.chunk(" << cnt << ", PIVector<" << ptype << " >((const " << ptype << " *)(" << "v." << var_prefix
<< m.name << "), ";
rt.ts << size << "));\n";
}
}
if (is_union) break;
}
if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
if (!writeClassStreamMembersOut(rt, ce, cnt, simple)) return false;
}
return true;
}
bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple) {
bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix) {
if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += ".";
PIVector<PICodeParser::Member> ml;
for (const PICodeParser::Member & m: e->members) {
if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue;
@@ -85,9 +91,16 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
bool is_union = e->type == "union";
PISet<int> used_id;
for (const PICodeParser::Member & m: ml) {
if (is_union && m.isBitfield()) continue;
if (m.isBitfield()) continue;
if (m.attributes[PICodeParser::Static]) continue;
if (m.meta.value("id") == "-") continue;
auto type = findEntity(rt, m.type);
if (type) {
if (type->is_anonymous) {
if (!writeClassStreamMembersIn(rt, type, cnt, simple, var_prefix + m.name)) return false;
continue;
}
}
++cnt;
if (m.meta.contains("id")) cnt = m.meta.value("id").toInt();
if (used_id[cnt]) {
@@ -104,8 +117,8 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
if (is_enum)
rt.ts << "i;";
else
rt.ts << "v." << m.name << ";";
if (is_enum) rt.ts << " v." << m.name << " = (" << m.type << ")i;}";
rt.ts << "v." << var_prefix << m.name << ";";
if (is_enum) rt.ts << " v. << var_prefix" << m.name << " = (" << m.type << ")i;}";
rt.ts << "\n";
} else {
rt.ts << "\t\tcase " << cnt << ":";
@@ -114,9 +127,9 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
if (is_enum)
rt.ts << "i";
else
rt.ts << "v." << m.name;
rt.ts << "v." << var_prefix << m.name;
rt.ts << ");";
if (is_enum) rt.ts << " v." << m.name << " = (" << m.type << ")i;}";
if (is_enum) rt.ts << " v." << var_prefix << m.name << " = (" << m.type << ")i;}";
rt.ts << " break;\n";
}
} else {
@@ -128,12 +141,12 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
}
if (simple) {
rt.ts << "\tfor (int i = 0; i < " << size << "; ++i)\n";
rt.ts << "\t\ts >> ((" << ptype << " *)(v." << m.name << "))[i];\n";
rt.ts << "\t\ts >> ((" << ptype << " *)(" << "v." << var_prefix << m.name << "))[i];\n";
} else {
rt.ts << "\t\tcase " << cnt << ": {\n\t\t\tPIVector<" << ptype << " > d; cs.get(d);\n";
rt.ts << "\t\t\tint cnt = piMini(d.size_s(), " << size << ");\n";
rt.ts << "\t\t\tfor (int i = 0; i < cnt; ++i)\n";
rt.ts << "\t\t\t\t((" << ptype << " *)(v." << m.name << "))[i] = d[i];\n";
rt.ts << "\t\t\t\t((" << ptype << " *)(" << "v." << var_prefix << m.name << "))[i] = d[i];\n";
rt.ts << "\t\t\t}\n";
rt.ts << "\t\t\tbreak;\n";
}
@@ -141,10 +154,6 @@ bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int
if (is_union) break;
}
if (is_union) return true;
for (const PICodeParser::Entity * ce: e->children) {
if (ce->has_name) continue;
if (!writeClassStreamMembersIn(rt, ce, cnt, simple)) return false;
}
return true;
}

View File

@@ -22,8 +22,8 @@
#include "common.h"
bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple);
bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple);
bool writeClassStreamMembersOut(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix = {});
bool writeClassStreamMembersIn(Runtime & rt, const PICodeParser::Entity * e, int & cnt, bool simple, PIString var_prefix = {});
bool needClassStream(const PICodeParser::Entity * e);
bool makeClassStream(Runtime & rt, const PICodeParser::Entity * e);