Ezc::ReadFile has gone
Ezc::CreateTree takes a name of an input file added [for ...] added [if-index ...] added [is ....] added [include...] (not all finished) git-svn-id: svn://ttmath.org/publicrep/cgi/ezc/trunk@6 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
ac632987f3
commit
043a5f2131
363
src/ezc.cpp
363
src/ezc.cpp
|
@ -8,23 +8,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Ezc::ReadFile(const char * name)
|
|
||||||
{
|
|
||||||
std::ifstream file(name);
|
|
||||||
|
|
||||||
if( !file )
|
|
||||||
{
|
|
||||||
std::ostringstream buffer;
|
|
||||||
buffer << "<!-- ezc: can't open: " << name << " -->";
|
|
||||||
input = buffer.str();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::getline(file, input, '\0');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Ezc::Init()
|
void Ezc::Init()
|
||||||
|
@ -37,13 +20,14 @@ Ezc::Ezc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ezc::CreateTree()
|
void Ezc::CreateTree(const char * file)
|
||||||
{
|
{
|
||||||
item_root.ClearTable();
|
std::string file_name = "\"";
|
||||||
item_root.type = Item::item_container;
|
file_name += file;
|
||||||
|
|
||||||
const char * pinput = input.c_str();
|
item_root.directives.clear();
|
||||||
item_root.CreateTree(pinput);
|
item_root.directives.push_back( file_name );
|
||||||
|
item_root.CreateTreeReadInclude();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +46,7 @@ void Ezc::Insert(const std::string & key, UserFunction ufunction)
|
||||||
{
|
{
|
||||||
UserInfo ui;
|
UserInfo ui;
|
||||||
ui.user_function = ufunction;
|
ui.user_function = ufunction;
|
||||||
|
ui.iter = 0;
|
||||||
|
|
||||||
user_info_table.insert( std::make_pair(key, ui) );
|
user_info_table.insert( std::make_pair(key, ui) );
|
||||||
}
|
}
|
||||||
|
@ -105,6 +90,23 @@ Ezc::Item::~Item()
|
||||||
ClearTable();
|
ClearTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ezc::Item::ReadFile(const char * name, std::string & result)
|
||||||
|
{
|
||||||
|
std::ifstream file(name);
|
||||||
|
|
||||||
|
if( !file )
|
||||||
|
{
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << "<!-- ezc: can't open: " << name << " -->";
|
||||||
|
result = buffer.str();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::getline(file, result, '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Ezc::Item::ItemType Ezc::Item::LastItemType()
|
Ezc::Item::ItemType Ezc::Item::LastItemType()
|
||||||
{
|
{
|
||||||
if( item_table.empty() )
|
if( item_table.empty() )
|
||||||
|
@ -153,7 +155,7 @@ void Ezc::Item::ReadDirective(const char * & itext, std::string & directive)
|
||||||
while( (*itext>='a' && *itext<='z') ||
|
while( (*itext>='a' && *itext<='z') ||
|
||||||
(*itext>='A' && *itext<='Z') ||
|
(*itext>='A' && *itext<='Z') ||
|
||||||
(*itext>='0' && *itext<='9') ||
|
(*itext>='0' && *itext<='9') ||
|
||||||
*itext=='_' || *itext=='-' )
|
*itext=='_' || *itext=='-' || *itext=='.' )
|
||||||
{
|
{
|
||||||
directive += *itext;
|
directive += *itext;
|
||||||
|
|
||||||
|
@ -161,6 +163,60 @@ void Ezc::Item::ReadDirective(const char * & itext, std::string & directive)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Ezc::Item::ReadString(const char * & itext, std::string & directive)
|
||||||
|
{
|
||||||
|
directive.clear();
|
||||||
|
|
||||||
|
SkipWhiteCharacters(itext);
|
||||||
|
|
||||||
|
if( *itext != '\"' )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// string is signed by its first character equal (")
|
||||||
|
directive += *itext;
|
||||||
|
++itext;
|
||||||
|
|
||||||
|
while( (*itext>='a' && *itext<='z') ||
|
||||||
|
(*itext>='A' && *itext<='Z') ||
|
||||||
|
(*itext>='0' && *itext<='9') ||
|
||||||
|
*itext=='_' || *itext=='-' || *itext=='.' || *itext==' '
|
||||||
|
|| *itext==':' || *itext=='\\' )// tymczasowo
|
||||||
|
{
|
||||||
|
directive += *itext;
|
||||||
|
|
||||||
|
++itext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( *itext != '\"' )
|
||||||
|
{
|
||||||
|
// the second quotation mark (") is missing
|
||||||
|
directive.clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++itext;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the second quotation mark (") we don't add into the 'directive'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ezc::Item::ReadDirectiveOrString(const char * & itext, std::string & directive)
|
||||||
|
{
|
||||||
|
SkipWhiteCharacters(itext);
|
||||||
|
|
||||||
|
if( *itext == '\"' )
|
||||||
|
{
|
||||||
|
// we've got string
|
||||||
|
return ReadString(itext, directive);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ReadDirective(itext, directive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ezc::Item::CreateTreeReadItemDirectiveCheckEnding(const char * & itext)
|
void Ezc::Item::CreateTreeReadItemDirectiveCheckEnding(const char * & itext)
|
||||||
{
|
{
|
||||||
SkipWhiteCharacters(itext);
|
SkipWhiteCharacters(itext);
|
||||||
|
@ -200,6 +256,49 @@ std::string directive;
|
||||||
|
|
||||||
directives.push_back(directive);
|
directives.push_back(directive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( directives.empty() )
|
||||||
|
type = item_err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( directive == "is" )
|
||||||
|
{
|
||||||
|
type = item_is;
|
||||||
|
|
||||||
|
ReadDirective(itext,directive);
|
||||||
|
|
||||||
|
if( !directive.empty() )
|
||||||
|
{
|
||||||
|
directives.push_back(directive);
|
||||||
|
|
||||||
|
ReadDirectiveOrString(itext,directive);
|
||||||
|
|
||||||
|
if( !directive.empty() )
|
||||||
|
directives.push_back(directive);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( directives.size() != 2 )
|
||||||
|
type = item_err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( directive == "if-index" )
|
||||||
|
{
|
||||||
|
type = item_ifindex;
|
||||||
|
|
||||||
|
ReadDirective(itext,directive);
|
||||||
|
|
||||||
|
if( !directive.empty() )
|
||||||
|
{
|
||||||
|
directives.push_back(directive);
|
||||||
|
|
||||||
|
ReadDirective(itext,directive);
|
||||||
|
|
||||||
|
if( !directive.empty() )
|
||||||
|
directives.push_back(directive);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( directives.size() != 2 )
|
||||||
|
type = item_err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if( directive == "end" )
|
if( directive == "end" )
|
||||||
|
@ -220,6 +319,20 @@ std::string directive;
|
||||||
|
|
||||||
if( !directive.empty() )
|
if( !directive.empty() )
|
||||||
directives.push_back(directive);
|
directives.push_back(directive);
|
||||||
|
else
|
||||||
|
type = item_err;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( directive == "include" )
|
||||||
|
{
|
||||||
|
type = item_include;
|
||||||
|
|
||||||
|
ReadString(itext,directive);
|
||||||
|
|
||||||
|
if( !directive.empty() )
|
||||||
|
directives.push_back(directive);
|
||||||
|
else
|
||||||
|
type = item_err;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -264,24 +377,6 @@ return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ezc::Item::CreateTreeReadAll(const char * & itext)
|
|
||||||
{
|
|
||||||
Item item;
|
|
||||||
|
|
||||||
while( item.CreateTreeReadItem(itext) )
|
|
||||||
{
|
|
||||||
AddItem(item);
|
|
||||||
|
|
||||||
if( item.type==item_end || item.type==item_else )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( item.type == Item::item_ifany )
|
|
||||||
item_table.back()->CreateTreeReadIfany(itext);
|
|
||||||
|
|
||||||
if( item.type == Item::item_for )
|
|
||||||
item_table.back()->CreateTreeReadFor(itext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Ezc::Item::CreateTreeReadDeleteLastEndItem()
|
bool Ezc::Item::CreateTreeReadDeleteLastEndItem()
|
||||||
{
|
{
|
||||||
|
@ -300,7 +395,25 @@ bool Ezc::Item::CreateTreeReadDeleteLastEndItem()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ezc::Item::CreateTreeReadIfany(const char * & itext)
|
void Ezc::Item::CreateTreeReadInclude()
|
||||||
|
{
|
||||||
|
if( directives.empty() || directives[0].empty() || directives[0][0]!='\"' )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ClearTable();
|
||||||
|
type = item_container;
|
||||||
|
|
||||||
|
std::string file_text;
|
||||||
|
|
||||||
|
ReadFile(directives[0].c_str()+1, file_text);
|
||||||
|
|
||||||
|
const char * pinput = file_text.c_str();
|
||||||
|
CreateTree(pinput);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ezc::Item::CreateTreeReadIf(const char * & itext)
|
||||||
{
|
{
|
||||||
Item item;
|
Item item;
|
||||||
|
|
||||||
|
@ -344,8 +457,29 @@ Item item;
|
||||||
|
|
||||||
void Ezc::Item::CreateTree(const char * & itext)
|
void Ezc::Item::CreateTree(const char * & itext)
|
||||||
{
|
{
|
||||||
if( type == item_container)
|
if( type != item_container)
|
||||||
CreateTreeReadAll(itext);
|
return;
|
||||||
|
|
||||||
|
Item item;
|
||||||
|
|
||||||
|
while( item.CreateTreeReadItem(itext) )
|
||||||
|
{
|
||||||
|
AddItem(item);
|
||||||
|
|
||||||
|
if( item.type==item_end || item.type==item_else )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( item.type == Item::item_ifany ||
|
||||||
|
item.type == Item::item_ifindex ||
|
||||||
|
item.type == Item::item_is )
|
||||||
|
item_table.back()->CreateTreeReadIf(itext);
|
||||||
|
|
||||||
|
if( item.type == Item::item_for )
|
||||||
|
item_table.back()->CreateTreeReadFor(itext);
|
||||||
|
|
||||||
|
if( item.type == item_include )
|
||||||
|
item_table.back()->CreateTreeReadInclude();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -430,6 +564,132 @@ void Ezc::Item::MakeTextIfany(std::string & otext, UserInfoTable & user_info_tab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Ezc::Item::MakeTextIs(std::string & otext, UserInfoTable & user_info_table)
|
||||||
|
{
|
||||||
|
if( directives.size() != 2 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
UserInfoTable::iterator i = user_info_table.find( directives[0] );
|
||||||
|
|
||||||
|
if( i != user_info_table.end() )
|
||||||
|
{
|
||||||
|
Info info1, info2;
|
||||||
|
info1.result = info2.result = false;
|
||||||
|
info1.iter = info2.iter = 0;
|
||||||
|
(i->second.user_function)(info1);
|
||||||
|
|
||||||
|
if( !directives[1].empty() && directives[1][0]=='\"' )
|
||||||
|
{
|
||||||
|
if( std::strcmp(info1.text.c_str(), directives[1].c_str()+1) == 0 )
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = user_info_table.find( directives[1] );
|
||||||
|
|
||||||
|
if( i != user_info_table.end() )
|
||||||
|
{
|
||||||
|
(i->second.user_function)(info2);
|
||||||
|
|
||||||
|
if( info1.result==info2.result && info1.text==info2.text )
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MakeTextMsgCantFind(otext, directives[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MakeTextMsgCantFind(otext, directives[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if( result )
|
||||||
|
{
|
||||||
|
// one element should be in the table (but we're testing)
|
||||||
|
if( item_table.size() > 0 )
|
||||||
|
item_table[0]->MakeText(otext, user_info_table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// second element can be (or not -- it's from [else])
|
||||||
|
if( item_table.size() > 1 )
|
||||||
|
item_table[1]->MakeText(otext, user_info_table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Ezc::Item::MakeTextIfindex(std::string & otext, UserInfoTable & user_info_table)
|
||||||
|
{
|
||||||
|
if( directives.size() != 2 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
UserInfoTable::iterator i = user_info_table.find( directives[0] );
|
||||||
|
|
||||||
|
if( i == user_info_table.end() )
|
||||||
|
{
|
||||||
|
MakeTextMsgCantFind(otext, directives[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
if( directives[1] == "odd" )
|
||||||
|
{
|
||||||
|
if( ( i->second.iter & 1) == 1 )
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( directives[1] == "even" )
|
||||||
|
{
|
||||||
|
if( ( i->second.iter & 1) == 0 )
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( directives[1] == "first" )
|
||||||
|
{
|
||||||
|
if( i->second.iter == 0 )
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const char * number_text = directives[1].c_str();
|
||||||
|
char * last_char;
|
||||||
|
|
||||||
|
int number = (int)strtol(number_text, &last_char, 10);
|
||||||
|
|
||||||
|
if( *last_char == '\0' )
|
||||||
|
{
|
||||||
|
if( i->second.iter == number )
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
otext += "<!-- ezc: if-index syntax error -->";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( result )
|
||||||
|
{
|
||||||
|
// one element should be in the table (but we're testing)
|
||||||
|
if( item_table.size() > 0 )
|
||||||
|
item_table[0]->MakeText(otext, user_info_table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// second element can be (or not -- it's from [else])
|
||||||
|
if( item_table.size() > 1 )
|
||||||
|
item_table[1]->MakeText(otext, user_info_table);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table)
|
void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table)
|
||||||
{
|
{
|
||||||
if( directives.empty() )
|
if( directives.empty() )
|
||||||
|
@ -449,14 +709,15 @@ void Ezc::Item::MakeTextFor(std::string & otext, UserInfoTable & user_info_table
|
||||||
while( true )
|
while( true )
|
||||||
{
|
{
|
||||||
(i->second.user_function)(info);
|
(i->second.user_function)(info);
|
||||||
++info.iter;
|
|
||||||
i->second.iter = info.iter;
|
|
||||||
|
|
||||||
if( info.text.empty() && !info.result )
|
if( info.text.empty() && !info.result )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( item_table.size() > 0 )
|
if( item_table.size() > 0 )
|
||||||
item_table[0]->MakeText(otext, user_info_table);
|
item_table[0]->MakeText(otext, user_info_table);
|
||||||
|
|
||||||
|
++info.iter;
|
||||||
|
i->second.iter = info.iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -488,6 +749,16 @@ void Ezc::Item::MakeText(std::string & otext, UserInfoTable & user_info_table)
|
||||||
MakeTextIfany(otext, user_info_table);
|
MakeTextIfany(otext, user_info_table);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
if( type == item_ifindex )
|
||||||
|
{
|
||||||
|
MakeTextIfindex(otext, user_info_table);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if( type == item_is )
|
||||||
|
{
|
||||||
|
MakeTextIs(otext, user_info_table);
|
||||||
|
}
|
||||||
|
else
|
||||||
if( type == item_for )
|
if( type == item_for )
|
||||||
{
|
{
|
||||||
MakeTextFor(otext, user_info_table);
|
MakeTextFor(otext, user_info_table);
|
||||||
|
|
17
src/ezc.h
17
src/ezc.h
|
@ -6,6 +6,8 @@
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
class Ezc
|
class Ezc
|
||||||
|
@ -32,8 +34,7 @@ public:
|
||||||
|
|
||||||
Ezc();
|
Ezc();
|
||||||
void Init();
|
void Init();
|
||||||
bool ReadFile(const char * name);
|
void CreateTree(const char * file);
|
||||||
void CreateTree();
|
|
||||||
std::string MakeText();
|
std::string MakeText();
|
||||||
void Insert(const std::string & key, UserFunction ufunction);
|
void Insert(const std::string & key, UserFunction ufunction);
|
||||||
|
|
||||||
|
@ -43,7 +44,7 @@ private:
|
||||||
enum ItemType
|
enum ItemType
|
||||||
{
|
{
|
||||||
item_none, item_container, item_text, item_ifany, item_for, item_else,
|
item_none, item_container, item_text, item_ifany, item_for, item_else,
|
||||||
item_end, item_err, item_normal
|
item_end, item_err, item_normal, item_ifindex, item_include, item_is
|
||||||
};
|
};
|
||||||
|
|
||||||
ItemType type;
|
ItemType type;
|
||||||
|
@ -55,8 +56,11 @@ private:
|
||||||
Item();
|
Item();
|
||||||
~Item();
|
~Item();
|
||||||
Item * AddItem(const Item & porg);
|
Item * AddItem(const Item & porg);
|
||||||
|
void ReadFile(const char * name, std::string & result);
|
||||||
void SkipWhiteCharacters(const char * & itext);
|
void SkipWhiteCharacters(const char * & itext);
|
||||||
void ReadDirective(const char * & itext, std::string & directive);
|
void ReadDirective(const char * & itext, std::string & directive);
|
||||||
|
void ReadString(const char * & itext, std::string & directive);
|
||||||
|
void ReadDirectiveOrString(const char * & itext, std::string & directive);
|
||||||
void ClearTable();
|
void ClearTable();
|
||||||
ItemType LastItemType();
|
ItemType LastItemType();
|
||||||
bool ReadChar(const char * & itext, char & result);
|
bool ReadChar(const char * & itext, char & result);
|
||||||
|
@ -64,18 +68,19 @@ private:
|
||||||
void CreateTreeReadItemDirective(const char * & itext);
|
void CreateTreeReadItemDirective(const char * & itext);
|
||||||
void CreateTreeReadItemText(const char * & itext);
|
void CreateTreeReadItemText(const char * & itext);
|
||||||
bool CreateTreeReadItem(const char * & itext);
|
bool CreateTreeReadItem(const char * & itext);
|
||||||
void CreateTreeReadAll(const char * & itext);
|
void CreateTreeReadIf(const char * & itext);
|
||||||
void CreateTreeReadIfany(const char * & itext);
|
|
||||||
void CreateTreeReadFor(const char * & itext);
|
void CreateTreeReadFor(const char * & itext);
|
||||||
bool CreateTreeReadDeleteLastEndItem();
|
bool CreateTreeReadDeleteLastEndItem();
|
||||||
|
void CreateTreeReadInclude();
|
||||||
void CreateTree(const char * & itext);
|
void CreateTree(const char * & itext);
|
||||||
|
|
||||||
void MakeTextIfany(std::string & otext, UserInfoTable & user_info_table);
|
void MakeTextIfany(std::string & otext, UserInfoTable & user_info_table);
|
||||||
|
void MakeTextIfindex(std::string & otext, UserInfoTable & user_info_table);
|
||||||
void MakeTextFor(std::string & otext, UserInfoTable & user_info_table);
|
void MakeTextFor(std::string & otext, UserInfoTable & user_info_table);
|
||||||
void MakeTextContainer(std::string & otext, UserInfoTable & user_info_table);
|
void MakeTextContainer(std::string & otext, UserInfoTable & user_info_table);
|
||||||
void MakeTextMsgCantFind(std::string & otext, std::string & key);
|
void MakeTextMsgCantFind(std::string & otext, std::string & key);
|
||||||
void MakeTextNormal(std::string & otext, UserInfoTable & user_info_table);
|
void MakeTextNormal(std::string & otext, UserInfoTable & user_info_table);
|
||||||
|
void MakeTextIs(std::string & otext, UserInfoTable & user_info_table);
|
||||||
void MakeText(std::string & otext,UserInfoTable & user_info_table);
|
void MakeText(std::string & otext,UserInfoTable & user_info_table);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue