mirror of
https://github.com/msojocs/wx-compiler.git
synced 2025-07-19 00:00:04 +08:00
fix: transit_table
This commit is contained in:
parent
c99d9105f3
commit
9cc0ee2e3c
@ -55,7 +55,22 @@ add_executable(
|
|||||||
add_executable(test1
|
add_executable(test1
|
||||||
test/test.cpp
|
test/test.cpp
|
||||||
)
|
)
|
||||||
|
add_executable(
|
||||||
|
transit_table
|
||||||
|
test/transit_table.cpp
|
||||||
|
src/wxml/expr_lib/base.cpp
|
||||||
|
src/wxml/expr_lib/bnf.cpp
|
||||||
|
src/wxml/expr_lib/common.cpp
|
||||||
|
src/wxml/expr_lib/expr_syntax_tree.cpp
|
||||||
|
src/wxml/expr_lib/parser.cpp
|
||||||
|
src/wxml/expr_lib/token.cpp
|
||||||
|
src/wxml/expr_lib/tokenizer.cpp
|
||||||
|
src/wxml/expr_lib/transit_table.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_test(transit_table_test
|
||||||
|
$<TARGET_FILE:transit_table>
|
||||||
|
)
|
||||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
@ -533,20 +533,22 @@ namespace WXML
|
|||||||
/**
|
/**
|
||||||
* 内存结构:
|
* 内存结构:
|
||||||
* 00 00 00 00 标识type
|
* 00 00 00 00 标识type
|
||||||
* 00 00 00 00... 当标识为0时后面为需要的动态字符串tokenName
|
* 00 00 00 00... 当标识为0时后面为需要的动态字符串tokenName(char *)
|
||||||
* /////
|
* /////
|
||||||
* 03 00 00 00 00 00 00 00 00 00 00 00 70 87 E8 00(std::string地址)
|
* 03 00 00 00 00 00 00 00 00 00 00 00 70 87 E8 00(std::string地址)
|
||||||
|
* 00 00 00 00(回调地址)
|
||||||
*/
|
*/
|
||||||
private:
|
private:
|
||||||
/* data */
|
/* data */
|
||||||
public:
|
public:
|
||||||
int offset_0 = 0;
|
int offset_0 = 0;
|
||||||
std::string offset_4;
|
std::string offset_4 = "";
|
||||||
std::string offset_16;
|
std::string offset_12;
|
||||||
|
// offset_16;
|
||||||
Token(/* args */);
|
Token(/* args */);
|
||||||
~Token();
|
~Token();
|
||||||
std::string GetLiteral(void);
|
std::string GetLiteral(void);
|
||||||
const char * GetTokenName();
|
std::string GetTokenName();
|
||||||
};
|
};
|
||||||
|
|
||||||
using Offset0Type = int();
|
using Offset0Type = int();
|
||||||
@ -595,9 +597,9 @@ namespace WXML
|
|||||||
static std::mutex m;
|
static std::mutex m;
|
||||||
static WXML::EXPRLib::TransitTable* instance;
|
static WXML::EXPRLib::TransitTable* instance;
|
||||||
void Init_55F1E4(int root, std::string & key, std::vector<int>& offset4List);
|
void Init_55F1E4(int root, std::string & key, std::vector<int>& offset4List);
|
||||||
void Init_55F1E4_6(int root, std::string & key);
|
|
||||||
void Init_55F1F8(int root, std::string & key);
|
void Init_55F1F8(int root, std::string & key);
|
||||||
void Init_55F220_0(int root, std::string & key, std::string & offset_4);
|
void Init_55F220_0(int root, std::string & key, std::string & offset_4);
|
||||||
|
void Init_55F20C(int root, std::string & key, std::string & offset_4, int offset_32, std::string &offset_36);
|
||||||
public:
|
public:
|
||||||
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>> ret;
|
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>> ret;
|
||||||
bool offset_24;
|
bool offset_24;
|
||||||
|
@ -51,8 +51,8 @@ namespace WXML
|
|||||||
// RenderAsOps - 5
|
// RenderAsOps - 5
|
||||||
if (
|
if (
|
||||||
this->offset_0[0] == 'O'
|
this->offset_0[0] == 'O'
|
||||||
&& this->offset_0[0] == 'P'
|
&& this->offset_0[1] == 'P'
|
||||||
&& this->offset_0[0] == '_'
|
&& this->offset_0[2] == '_'
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (this->offset_0 == "OP_PATH")
|
if (this->offset_0 == "OP_PATH")
|
||||||
|
@ -83,9 +83,11 @@ namespace WXML
|
|||||||
this->offset_0.push_back(v70);
|
this->offset_0.push_back(v70);
|
||||||
// WXML::EXPRLib::Parser::Parse - 20
|
// WXML::EXPRLib::Parser::Parse - 20
|
||||||
int v49 = 0;
|
int v49 = 0;
|
||||||
for(auto cur = this->offset_0.rbegin(); cur != this->offset_0.rend(); cur++)
|
while (true)
|
||||||
{
|
{
|
||||||
auto v72 = *cur;
|
if (this->offset_0.begin() == this->offset_0.end())
|
||||||
|
break;
|
||||||
|
auto v72 = *this->offset_0.rbegin();
|
||||||
WXML::EXPRLib::Token v84 = v74[v49]; // ???
|
WXML::EXPRLib::Token v84 = v74[v49]; // ???
|
||||||
int v15 = v72->offset_0();
|
int v15 = v72->offset_0();
|
||||||
// WXML::EXPRLib::Parser::Parse - 20-1
|
// WXML::EXPRLib::Parser::Parse - 20-1
|
||||||
@ -145,8 +147,7 @@ namespace WXML
|
|||||||
///////////////////////
|
///////////////////////
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::shared_ptr<WXML::EXPRLib::ExprSyntaxTree> v22(new WXML::EXPRLib::ExprSyntaxTree());
|
std::shared_ptr<WXML::EXPRLib::ExprSyntaxTree> v78(new WXML::EXPRLib::ExprSyntaxTree());
|
||||||
std::shared_ptr<WXML::EXPRLib::ExprSyntaxTree> v78;
|
|
||||||
v78->offset_0.assign(v72->offset_4_str);
|
v78->offset_0.assign(v72->offset_4_str);
|
||||||
for (size_t i = 0; i < v72->offset_32; i++)
|
for (size_t i = 0; i < v72->offset_32; i++)
|
||||||
{
|
{
|
||||||
@ -207,12 +208,13 @@ namespace WXML
|
|||||||
this->offset_0.pop_back();
|
this->offset_0.pop_back();
|
||||||
std::string v80 = v84.GetTokenName();
|
std::string v80 = v84.GetTokenName();
|
||||||
std::vector<WXML::EXPRLib::BNF> v53 = bnfMap[v80];
|
std::vector<WXML::EXPRLib::BNF> v53 = bnfMap[v80];
|
||||||
for (int i = v53.size() - 1; i >= 0; i--)
|
std::vector<std::shared_ptr<WXML::EXPRLib::Base>> baseList = v53[0].offset_0;
|
||||||
|
for (int i = baseList.size() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
auto cur = v53[i];
|
std::shared_ptr<WXML::EXPRLib::Base> cur1 = baseList[i];
|
||||||
if( v53[i].offset_8() == 4)
|
if( cur1->offset_0() == 4)
|
||||||
break;
|
break;
|
||||||
this->offset_0.push_back(v53[i].offset_0[0]);
|
this->offset_0.push_back(cur1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,9 @@ namespace WXML
|
|||||||
Token::~Token()
|
Token::~Token()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
const char * Token::GetTokenName()
|
std::string Token::GetTokenName()
|
||||||
{
|
{
|
||||||
const char *result;
|
std::string result = "$";
|
||||||
switch ( this->offset_0 )
|
switch ( this->offset_0 )
|
||||||
{
|
{
|
||||||
case 0u:
|
case 0u:
|
||||||
@ -48,9 +48,9 @@ namespace WXML
|
|||||||
if (this->offset_0 != 5)
|
if (this->offset_0 != 5)
|
||||||
{
|
{
|
||||||
result = "";
|
result = "";
|
||||||
if (this->offset_16.size())
|
if (this->offset_12.size())
|
||||||
{
|
{
|
||||||
return this->offset_16;
|
return this->offset_12;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,8 +236,9 @@ namespace WXML {
|
|||||||
if (v8)
|
if (v8)
|
||||||
{
|
{
|
||||||
const char **v31 = KEYWORDS;
|
const char **v31 = KEYWORDS;
|
||||||
std::string v26 = this->offset_0.substr(v29, v27 + 1);
|
std::string v26 = this->offset_0.substr(v29, v27 + 1 - v29);
|
||||||
|
|
||||||
|
v39.offset_12 = v26;
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if (!strcmp(v26.data(), v31[i]))
|
if (!strcmp(v26.data(), v31[i]))
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2969,6 +2969,7 @@ void __fastcall WXML::EXPRLib::TransitTable::Init(int a1)
|
|||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v136);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v136);
|
||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1510);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1510);
|
||||||
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
||||||
|
////////////////// root - 4 ////////////////////
|
||||||
v137 = std::_Rb_tree_header::_Rb_tree_header(v1511);
|
v137 = std::_Rb_tree_header::_Rb_tree_header(v1511);
|
||||||
v1979 = 4;
|
v1979 = 4;
|
||||||
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v137);
|
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v137);
|
||||||
@ -3266,6 +3267,7 @@ void __fastcall WXML::EXPRLib::TransitTable::Init(int a1)
|
|||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v178);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v178);
|
||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1521);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1521);
|
||||||
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
||||||
|
////////////////// root - 5 ////////////////////
|
||||||
v179 = std::_Rb_tree_header::_Rb_tree_header(v1522);
|
v179 = std::_Rb_tree_header::_Rb_tree_header(v1522);
|
||||||
v1979 = 5;
|
v1979 = 5;
|
||||||
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v179);
|
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v179);
|
||||||
@ -3563,6 +3565,7 @@ void __fastcall WXML::EXPRLib::TransitTable::Init(int a1)
|
|||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v220);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v220);
|
||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1532);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1532);
|
||||||
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
||||||
|
////////////////// root - 6 ////////////////////
|
||||||
v221 = std::_Rb_tree_header::_Rb_tree_header(v1533);
|
v221 = std::_Rb_tree_header::_Rb_tree_header(v1533);
|
||||||
v1979 = 6;
|
v1979 = 6;
|
||||||
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v221);
|
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v221);
|
||||||
@ -3860,6 +3863,7 @@ void __fastcall WXML::EXPRLib::TransitTable::Init(int a1)
|
|||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v262);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v262);
|
||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1543);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1543);
|
||||||
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
||||||
|
////////////////// root - 7 ////////////////////
|
||||||
v263 = std::_Rb_tree_header::_Rb_tree_header(v1544);
|
v263 = std::_Rb_tree_header::_Rb_tree_header(v1544);
|
||||||
v1979 = 7;
|
v1979 = 7;
|
||||||
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v263);
|
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v263);
|
||||||
@ -4157,6 +4161,7 @@ void __fastcall WXML::EXPRLib::TransitTable::Init(int a1)
|
|||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v304);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(&v1980, v304);
|
||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1554);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1978, v1554);
|
||||||
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1982);
|
||||||
|
////////////////// root - 8 ////////////////////
|
||||||
v305 = std::_Rb_tree_header::_Rb_tree_header(v1555);
|
v305 = std::_Rb_tree_header::_Rb_tree_header(v1555);
|
||||||
v1979 = 8;
|
v1979 = 8;
|
||||||
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v305);
|
std::map<int,std::map<std::string,std::vector<WXML::EXPRLib::BNF>>>::operator[](v305);
|
||||||
@ -4325,7 +4330,6 @@ void __fastcall WXML::EXPRLib::TransitTable::Init(int a1)
|
|||||||
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1974, v1560);
|
std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count(v1974, v1560);
|
||||||
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1979);
|
std::vector<zcc::shared_ptr<WXML::EXPRLib::Base>>::~vector(&v1979);
|
||||||
|
|
||||||
//////////////////////to be continue////////////
|
|
||||||
v1979 = 0;
|
v1979 = 0;
|
||||||
v1980 = 0;
|
v1980 = 0;
|
||||||
v1981 = 0;
|
v1981 = 0;
|
||||||
|
135
test/transit_table.cpp
Normal file
135
test/transit_table.cpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#include "../src/include/wxml.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void PrintVectorBase(std::vector<std::shared_ptr<WXML::EXPRLib::Base>> &ret)
|
||||||
|
{
|
||||||
|
bool isFirst = true;
|
||||||
|
for (auto &&i : ret)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
cout << "," << endl;
|
||||||
|
}
|
||||||
|
isFirst = false;
|
||||||
|
cout << "{" << endl;
|
||||||
|
if (i->offset_0 == WXML::EXPRLib::off_55F20C)
|
||||||
|
{
|
||||||
|
cout << "\"offset_0\": " << "\"0x55f20c\"," << endl;
|
||||||
|
cout << "\"offset_4\": \"" << i->offset_4_str << "\"," << endl;
|
||||||
|
cout << "\"offset_32\": " << i->offset_32 <<"," << endl;
|
||||||
|
cout << "\"offset_36\": \"" << i->offset_36 << "\"" << endl;
|
||||||
|
}
|
||||||
|
else if(i->offset_0 == WXML::EXPRLib::off_55F220)
|
||||||
|
{
|
||||||
|
cout << "\"offset_0\": " << "\"0x55f220\"," << endl;
|
||||||
|
cout << "\"offset_4\": \"" << i->offset_4_str << "\"," << endl;
|
||||||
|
cout << "\"offset_32\": 0," << endl;
|
||||||
|
cout << "\"offset_36\": \"<EMPTY std::string>\"" << endl;
|
||||||
|
}
|
||||||
|
else if(i->offset_0 == WXML::EXPRLib::off_55F1E4)
|
||||||
|
{
|
||||||
|
cout << "\"offset_0\": " << "\"0x55f1e4\"," << endl;
|
||||||
|
cout << "\"offset_4\": " << i->offset_4_int << "," << endl;
|
||||||
|
cout << "\"offset_32\": 0," << endl;
|
||||||
|
cout << "\"offset_36\": \"not available\"" << endl;
|
||||||
|
}
|
||||||
|
else if(i->offset_0 == WXML::EXPRLib::off_55F1F8)
|
||||||
|
{
|
||||||
|
cout << "\"offset_0\": " << "\"0x55f1f8\"," << endl;
|
||||||
|
cout << "\"offset_4\": \"0xabababab -> 0xabababab\"," << endl;
|
||||||
|
cout << "\"offset_32\": 0," << endl;
|
||||||
|
cout << "\"offset_36\": \"not available\"" << endl;
|
||||||
|
}
|
||||||
|
cout << "}" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
void PrintBNF(WXML::EXPRLib::BNF & ret)
|
||||||
|
{
|
||||||
|
cout << "{" << endl;
|
||||||
|
cout << "\"offset_0\": {" << endl;
|
||||||
|
// cout << "\"type\": \"std::vector\"," << endl;
|
||||||
|
cout << "\"size\": " << ret.offset_0.size() << "," << endl;
|
||||||
|
cout << "\"capacity\": " << ret.offset_0.capacity() << "," << endl;
|
||||||
|
cout << "\"data\": [" << endl;
|
||||||
|
PrintVectorBase(ret.offset_0);
|
||||||
|
cout << "]" << endl;
|
||||||
|
cout << "}" << endl;
|
||||||
|
cout << "}" << endl;
|
||||||
|
}
|
||||||
|
void PrintVectorBNF(std::vector<WXML::EXPRLib::BNF> &ret)
|
||||||
|
{
|
||||||
|
// cout << "\"type\": \"std::vector\"," << endl;
|
||||||
|
cout << "\"size\": " << ret.size() << "," << endl;
|
||||||
|
cout << "\"capacity\": " << ret.capacity() << "," << endl;
|
||||||
|
cout << "\"data\": [" << endl;
|
||||||
|
bool isFirst = true;
|
||||||
|
for (auto &&i : ret)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
cout << ",";
|
||||||
|
}
|
||||||
|
isFirst = false;
|
||||||
|
PrintBNF(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "]" << endl;
|
||||||
|
}
|
||||||
|
void PrintMapString(std::map<std::string, std::vector<WXML::EXPRLib::BNF>> &ret)
|
||||||
|
{
|
||||||
|
|
||||||
|
// cout << "{" << endl;
|
||||||
|
cout << "\"size\": " << ret.size() << "," << endl;
|
||||||
|
cout << "\"data\": [" << endl;
|
||||||
|
bool isFirst = true;
|
||||||
|
for (auto &&i : ret)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
cout << ",";
|
||||||
|
}
|
||||||
|
isFirst = false;
|
||||||
|
cout << "{" << endl;
|
||||||
|
cout << "\"key\": \"" << i.first << "\"," << endl;
|
||||||
|
cout << "\"value\": {" << endl;
|
||||||
|
PrintVectorBNF(i.second);
|
||||||
|
cout << "}" << endl;
|
||||||
|
cout << "}" << endl;
|
||||||
|
}
|
||||||
|
cout << "]" << endl;
|
||||||
|
// cout << "}" << endl;
|
||||||
|
}
|
||||||
|
void PrintMapInt(std::map<int, std::map<std::string, std::vector<WXML::EXPRLib::BNF>>>& ret)
|
||||||
|
{
|
||||||
|
cout << "{" << endl;
|
||||||
|
cout << "\"size\": " << ret.size() << "," << endl;
|
||||||
|
cout << "\"data\": [" << endl;
|
||||||
|
bool isFirst = true;
|
||||||
|
for (auto &&i : ret)
|
||||||
|
{
|
||||||
|
if (!isFirst)
|
||||||
|
{
|
||||||
|
cout << ",";
|
||||||
|
}
|
||||||
|
isFirst = false;
|
||||||
|
cout << "{" << endl;
|
||||||
|
cout << "\"key\": " << i.first << "," << endl;
|
||||||
|
cout << "\"value\": {" << endl;
|
||||||
|
PrintMapString(i.second);
|
||||||
|
cout << "}" << endl;
|
||||||
|
cout << "}" << endl;
|
||||||
|
}
|
||||||
|
cout << "]" << endl;
|
||||||
|
cout << "}" << endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
auto instance = WXML::EXPRLib::TransitTable::GetInstance();
|
||||||
|
instance->Init();
|
||||||
|
std::map<int, std::map<std::string, std::vector<WXML::EXPRLib::BNF>>> ret = instance->ret;
|
||||||
|
PrintMapInt(ret);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user