Sivelkiria Operating System repository

Commit c4a4262d authored by Alexey's avatar Alexey
Browse files

init

parent 6b29ef37
#include "interface_parser.hpp"
interface_parser::interface_parser( const std::string filename ) {
doc.LoadFile( filename.c_str() );
tinyxml2::XMLElement *ptr;
ptr= doc.FirstChildElement( "Interface" )->FirstChildElement();
has_template= strcmp( ptr->Name(), "Template" ) == 0;
if ( has_template ) parse_template( ptr );
ptr= doc.FirstChildElement( "Interface" );
if ( ptr != nullptr ) parse_interface( ptr );
}
void interface_parser::parse_template( tinyxml2::XMLElement *ptr ) {
tinyxml2::XMLNode *tmpnode;
for ( tinyxml2::XMLNode *node= ptr->FirstChild(); node != nullptr;
node= node->NextSibling() ) {
tinyxml2::XMLElement *elem= node->ToElement();
std::pair<std::string, std::string> tmp=
std::pair<std::string, std::string>(
std::string( elem->Attribute( "name" ) ),
std::string( elem->Attribute( "defval" ) ) );
templates.push_back( tmp );
tmpnode= node->FirstChild();
description_template_names.push_back(
std::string( tmpnode->ToElement()->GetText() ) ); // description
// tmpnode->ToElement()->Attribute(language)
}
}
void interface_parser::parse_interface( tinyxml2::XMLElement *ptr ) {
// ptr->ToElement()->Attribute("xsi:schemaLocation");
const char ch[]= "support-type";
supp_type= std::string( ptr->Attribute( ch ) );
tinyxml2::XMLNode *ptr2= ptr->FirstChild();
if ( strcmp( ptr2->ToElement()->Name(), "Template" ) == 0 )
ptr2= ptr2->NextSibling();
// name
name= std::string( ptr2->ToElement()->GetText() );
ptr2= ptr2->NextSibling(); // major
major= std::string( ptr2->ToElement()->GetText() );
ptr2= ptr2->NextSibling(); // minor-max
minor= std::string( ptr2->ToElement()->GetText() );
ptr2= ptr2->NextSibling(); // parse_permision()
parse_permission( ptr2, &perm );
ptr2= ptr2->NextSibling();
while ( strcmp( ptr2->ToElement()->Name(), "method" ) == 0 ) {
parse_method( ptr2 );
ptr2= ptr2->NextSibling();
}
description= std::string( ptr2->ToElement()->GetText() ); // get description
}
void interface_parser::parse_permission(
tinyxml2::XMLNode *ptr, permission *_perm ) {
//надо прописать как права выглядят//
tinyxml2::XMLElement *perm= ptr->ToElement();
const char *default_= perm->Attribute( "default" );
if ( default_ != nullptr )
_perm->default_perm= std::string( default_ ); // may be parse other fields
const char *caller_int= perm->Attribute( "caller-interface" );
if ( caller_int != nullptr ) _perm->caller_int= std::string( caller_int );
const char *caller_method= perm->Attribute( "caller-method" );
if ( caller_method != nullptr )
_perm->caller_method= std::string( caller_method );
const char *caller_obj= perm->Attribute( "caller-object" );
if ( caller_obj != nullptr ) _perm->caller_obj= std::string( caller_obj );
tinyxml2::XMLNode *tmp= ptr->FirstChild();
if ( tmp != nullptr ) { //если есть вложенные права
if ( _perm->subperm == nullptr ) //если нет вектора подправ
_perm->subperm= new std::vector<permission>; //то создаем его
while ( tmp != nullptr ) { //пока подправа еще не перебраны
_perm->subperm->push_back( *( new permission ) ); //добавляем право
parse_permission( tmp, &*_perm->subperm->rbegin() ); //применяем право
tmp= tmp->NextSibling(); //переключаемся на следующее подправо
}
} else
_perm->subperm= nullptr; //инициализируем на всякий
}
void interface_parser::parse_method( tinyxml2::XMLNode *ptr ) {
tinyxml2::XMLElement *method= ptr->ToElement();
methods.resize( methods.size() + 1 );
methods.rbegin()->name= std::string( method->Attribute( "name" ) );
methods.rbegin()->id= std::string( method->Attribute( "id" ) );
methods.rbegin()->minor_since=
std::string( method->Attribute( "minor-since" ) );
tinyxml2::XMLNode *tmp= ptr->FirstChild();
if ( strcmp( tmp->ToElement()->Name(), "cdata-default" ) == 0 ) {
// insert to generator//how?
tmp= tmp->NextSibling();
}
parse_permission( tmp, &( methods.rbegin()->perm ) );
description_methods.push_back( descr_method() );
tmp= tmp->NextSibling();
description_methods.rbegin()->descr_main=
std::string( tmp->ToElement()->GetText() ); // description
tmp= tmp->NextSibling();
std::string ret_type= std::string( tmp->ToElement()->Attribute( "type" ) );
std::pair<std::string, std::string> *p= nullptr;
for ( std::vector<std::pair<std::string, std::string>>::iterator it=
templates.begin();
it != templates.end(); ++it ) // find in templates
if ( it->first == ret_type ) {
p= &*it;
break;
}
methods.rbegin()->ret.first= ret_type;
methods.rbegin()->ret.second= p;
if ( tmp->FirstChildElement() != nullptr )
description_methods.rbegin()->descr_ret= std::string(
tmp->FirstChildElement()->GetText() ); // add description of return
else
description_methods.rbegin()->descr_ret= "";
tmp= tmp->NextSibling(); // arg
while ( tmp != nullptr ) {
parse_arg( tmp );
tmp= tmp->NextSibling(); // arg
}
}
void interface_parser::parse_arg( tinyxml2::XMLNode *ptr ) {
tinyxml2::XMLElement *arg= ptr->ToElement();
methods.rbegin()->args.resize( methods.rbegin()->args.size() + 1 );
std::vector<std::pair<_arg, std::pair<std::string, std::string> *>>::
reverse_iterator gt= methods.rbegin()->args.rbegin();
gt->first.mode= std::string( arg->Attribute( "mode" ) ); // get mode
gt->first.type= std::string( arg->Attribute( "type" ) ); // get type
gt->second= nullptr;
for ( std::vector<std::pair<std::string, std::string>>::iterator it=
templates.begin();
it != templates.end(); ++it ) // find in templates
if ( it->first == gt->first.type ) {
gt->second= &*it;
break;
}
gt->first.name= std::string( arg->Attribute( "name" ) ); // get name arg
gt->first.id= std::string( arg->Attribute( "id" ) ); // get arg id
std::string tmp= std::string( ptr->FirstChild()->ToElement()->GetText() );
description_methods.rbegin()->descr_arg.resize(
description_methods.rbegin()->descr_arg.size() + 1 );
*description_methods.rbegin()->descr_arg.rbegin()= tmp; // get description
}
#pragma once
#include "./tinyxml2.h"
#include <exception>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <iterator>
struct _arg {
std::string mode, type, name, id;
};
struct permission {
std::string default_perm, caller_int, caller_method, caller_obj;
std::vector<permission> *subperm= nullptr;
};
struct method {
//т к массив шиблонов уже не будет меняться, можно смело взять указатель
std::vector<std::pair<_arg, std::pair<std::string, std::string> *>>
args; // 2-е - указатель на шаблон
// if == nullptr => is not template
std::pair<std::string, std::pair<std::string, std::string> *> ret; // return
// if == nullptr => is not template
std::string name;
permission perm;
std::string id; //его можно в int не превращать
std::string minor_since;
};
struct descr_method {
std::string descr_main, descr_ret;
std::vector<std::string> descr_arg;
};
class interface_parser {
public:
std::string description;
bool has_template;
tinyxml2::XMLDocument doc;
std::vector<std::pair<std::string, std::string>> templates; // name and defval
std::vector<std::string> description_template_names;
std::vector<method> methods;
std::vector<descr_method> description_methods;
std::string supp_type, name, major, minor;
permission perm;
interface_parser( const std::string filename );
private:
void parse_template( tinyxml2::XMLElement *ptr );
void parse_interface( tinyxml2::XMLElement *ptr );
void parse_permission( tinyxml2::XMLNode *ptr, permission *_perm );
void parse_method( tinyxml2::XMLNode *ptr );
void parse_arg( tinyxml2::XMLNode *ptr );
};
#include "struct_parser.hpp"
struct_parser::struct_parser( const std::string filename ) {
doc.LoadFile( filename.c_str() );
tinyxml2::XMLElement *ptr;
ptr= doc.FirstChildElement( "Structure" )->FirstChildElement();
has_template= strcmp( ptr->Name(), "Template" ) == 0;
if ( has_template ) parse_template( ptr );
ptr= doc.FirstChildElement( "Structure" );
if ( ptr != nullptr ) parse_struct( ptr );
}
void struct_parser::parse_template( tinyxml2::XMLElement *ptr ) {
tinyxml2::XMLNode *tmpnode;
for ( tinyxml2::XMLNode *node= ptr->FirstChild(); node != nullptr;
node= node->NextSibling() ) {
tinyxml2::XMLElement *elem= node->ToElement();
std::pair<std::string, std::string> tmp=
std::pair<std::string, std::string>(
std::string( elem->Attribute( "name" ) ),
std::string( elem->Attribute( "defval" ) ) );
templates.push_back( tmp );
tmpnode= node->FirstChild();
description_template_names.push_back(
std::string( tmpnode->ToElement()->GetText() ) ); // description
// tmpnode->ToElement()->Attribute(language)
}
}
void struct_parser::parse_struct( tinyxml2::XMLElement *ptr ) {
// ptr->ToElement()->Attribute("xsi:schemaLocation");
const char ch[]= "support-type";
supp_type= std::string( ptr->Attribute( ch ) );
tinyxml2::XMLNode *ptr2= ptr->FirstChild();
if ( strcmp( ptr2->ToElement()->Name(), "Template" ) == 0 )
ptr2= ptr2->NextSibling();
// name
name= std::string( ptr2->ToElement()->GetText() );
ptr2= ptr2->NextSibling(); // major
major= std::string( ptr2->ToElement()->GetText() );
ptr2= ptr2->NextSibling(); // minor-max
minor= std::string( ptr2->ToElement()->GetText() );
ptr2= ptr2->NextSibling(); // first field
while ( strcmp( ptr2->ToElement()->Name(), "field" ) == 0 ) {
parse_field( ptr2 );
ptr2= ptr2->NextSibling();
}
description= std::string( ptr2->ToElement()->GetText() ); // get description
}
void struct_parser::parse_field( tinyxml2::XMLNode *ptr ) {
tinyxml2::XMLElement *arg= ptr->ToElement();
// methods.rbegin()->args.resize( methods.rbegin()->args.size() + 1 );
fields.resize( fields.size() + 1 );
std::vector<std::pair<_field, std::pair<std::string, std::string> *>>::
reverse_iterator gt= fields.rbegin();
gt->first.type= std::string( arg->Attribute( "type" ) ); // get type
gt->second= nullptr;
for ( std::vector<std::pair<std::string, std::string>>::iterator it=
templates.begin();
it != templates.end(); ++it ) // find in templates
if ( it->first == gt->first.type ) {
gt->second= &*it;
break;
}
gt->first.name= std::string( arg->Attribute( "name" ) ); // get name arg
gt->first.id= std::string( arg->Attribute( "id" ) ); // get arg id
std::string tmp= std::string( ptr->FirstChild()->ToElement()->GetText() );
fields_descriptions.resize( fields_descriptions.size() + 1 );
*fields_descriptions.rbegin()= tmp; // get description
}
#pragma once
#include "./tinyxml2.h"
#include <exception>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
#include <iterator>
struct _field {
std::string type, name, id;
};
class struct_parser {
public:
std::string description;
bool has_template;
tinyxml2::XMLDocument doc;
std::vector<std::pair<std::string, std::string>> templates; // name and defval
std::vector<std::string> description_template_names;
std::vector<std::pair<_field, std::pair<std::string, std::string> *>> fields;
std::vector<std::string> fields_descriptions;
std::string supp_type, name, major, minor;
struct_parser( const std::string filename );
private:
void parse_template( tinyxml2::XMLElement *ptr );
void parse_struct( tinyxml2::XMLElement *ptr );
void parse_field( tinyxml2::XMLNode *ptr );
};
This diff is collapsed.
This diff is collapsed.
#include "sdkbuilder.hpp"
#include <iostream>
int main() {
std::vector<std::pair<std::string, std::string>> vec;
vec.push_back( std::pair<std::string, std::string>(
"Interface", "../interfaces/Interface/ExampleCalculator.0.xml" ) );
vec.push_back( std::pair<std::string, std::string>(
"Structure", "../interfaces/Structure/ExampleTemperature.0.xml" ) );
sdkbuilder obj( vec, "./" );
}
#include "sdkbuilder.hpp"
sdkbuilder::sdkbuilder(
const std::vector<std::pair<std::string, std::string>>
&interfaces_filenames,
const std::string out_path )
: build_dir( out_path ) {
interface_parser *_interface_parser;
struct_parser *_struct_parser;
for ( std::vector<std::pair<std::string, std::string>>::const_iterator it=
interfaces_filenames.begin();
it != interfaces_filenames.end(); ++it ) {
if ( it->first == "Interface" ) {
_interface_parser= new interface_parser( it->second );
std::string class_name= _interface_parser->name.substr(
_interface_parser->name.find( "." ) + 1 ) +
"_" + _interface_parser->major;
std::string body=
generate_interface_body( _interface_parser, class_name );
if ( _interface_parser->minor != "0" )
class_name+= "_" + _interface_parser->minor;
std::string file_name= build_dir + class_name + ".hpp";
construct(
_interface_parser->description_template_names,
_interface_parser->templates, _interface_parser->has_template,
"class", class_name, body, file_name );
delete _interface_parser;
} else if ( it->first == "Structure" ) {
_struct_parser= new struct_parser( it->second.c_str() );
std::string struct_name=
_struct_parser->name.substr( _struct_parser->name.find( "." ) + 1 ) +
"_" + _struct_parser->major;
std::string body= generate_struct_body( _struct_parser, struct_name );
if ( _interface_parser->minor != "0" )
struct_name+= "_" + _struct_parser->minor;
std::string file_name= build_dir + struct_name + ".hpp";
construct(
_struct_parser->description_template_names, _struct_parser->templates,
_struct_parser->has_template, "struct", struct_name, body,
file_name );
delete _struct_parser;
}
}
}
void sdkbuilder::construct(
const std::vector<std::string> &descr_templ,
const std::vector<std::pair<std::string, std::string>> &templ,
const bool &has_template, const std::string type_obj,
const std::string normal_name, const std::string &body,
const std::string file_name ) {
std::string _templ;
std::string description_template;
if ( has_template ) {
description_template= "/*";
_templ= "template<";
std::vector<std::string>::const_iterator gt= descr_templ.begin();
for ( std::vector<std::pair<std::string, std::string>>::const_iterator it=
templ.begin();
it != templ.end(); ++it ) {
description_template= description_template + "\n*" + it->first + " - " +
*( gt++ ) + " Default:" + it->second;
_templ=
_templ + " " + type_obj + " " + it->first + " = " + it->second + ',';
}
description_template= description_template + "\n*/\n";
_templ.back()= ' '; //вставляем вместо последней запятой
_templ+= ">\n" + description_template;
}
construct_hpp( file_name, _templ, type_obj, body, normal_name );
}
void sdkbuilder::construct_hpp(
const std::string file_name, const std::string _template,
const std::string type_obj, const std::string &body,
const std::string &name ) {
std::ofstream hpp_file( file_name );
hpp_file << "namespace SivDK{\n" << "namespace ";
if(type_obj == "class")
hpp_file << "Interfaces";
else if (type_obj == "struct");
hpp_file << "Structures";
else
hpp_file << "Error";
hpp_file << "{\n" << _template << type_obj;
hpp_file << " " << name << body << "};\n};\n};";
}
std::string sdkbuilder::generate_interface_body(
const interface_parser *_interface_parser, const std::string normal_name ) {
std::string body= " : public virtual ";
if ( _interface_parser->minor != "0" ) body+= "SivDK::Object {";
else
body+= normal_name + " {"; //наследуем от 0-й мажорной версии
//тут еще описания методов добавить
std::string name= normal_name;
if ( _interface_parser->minor != "0" ) name+= "_" + _interface_parser->minor;
body+= "\n\tprotected:\n\t\t";
body+= name + "( SivDK::interface_handle handle );\n\t\t";
body+= name + "();\n\tpublic: virtual ~" + name;
body+= "() = default;\n";
std::vector<descr_method>::const_iterator gt=
_interface_parser->description_methods.begin();
for ( std::vector<method>::const_iterator it=
_interface_parser->methods.begin();
it != _interface_parser->methods.end(); ++it, ++gt ) {
body+= "/*\n";
body+= gt->descr_main + "\nreturn_type:" + gt->descr_ret;
body+= "\n*/\n\t";
//где-то тут вывести описания аргументов
if ( it->perm.default_perm == "allow" ) body+= "public: virtual ";
else if ( it->perm.default_perm == "deny" )
body+= "private: virtual ";
else {
; //выбросить ошибку или посмотреть вложенные правила
}
//каким-то образом запретить обращаться по правилам
//для вложенных allow friend методы?
body+= it->name + "("; //вывели имя метода
write_args( body, it );
body+= ") = 0;\n";
}
return body;
}
void sdkbuilder::write_args(
std::string &body, std::vector<method>::const_iterator &it ) {
for ( std::vector<std::pair<_arg, std::pair<std::string, std::string> *>>::
const_iterator gt= it->args.begin();
gt != it->args.end(); ++gt ) {
body+= " ";
if ( gt->first.mode == "in" )
body+= "const "; //но это не защитит-напр const int *p - данные можно
//менять
body+= gt->first.type + " ";
if ( gt->first.mode != "in" ) body+= "&";
body+= gt->first.name + ",";
}
body= body.substr( 0, body.size() - 2 ); //удаляем последнюю запятую
}
std::string sdkbuilder::generate_struct_body(
const struct_parser *_struct_parser, const std::string normal_name ) {
std::string code;
if ( _struct_parser->minor == "0" )
( code= " : public virtual " )+=
normal_name; //наследуем от 0-й мажорной версии
code+= " {\n";
std::vector<std::string>::const_iterator gt=
_struct_parser->fields_descriptions.begin();
for ( std::vector<std::pair<_field, std::pair<std::string, std::string> *>>::
const_iterator it= _struct_parser->fields.begin();
it != _struct_parser->fields.end(); ++it, ++gt ) {
// hpp_file << "/*" << std::endl
// << "name: " << it->first.name << " type: " << it->first.type << "
// - " << *gt << std::endl << "*/" << std::endl;
code+= '\t';
code+= it->first.type + " " + it->first.name + ";\n";
}
return code;
}
#pragma once
#include <vector>
#include <string>
#include "libs/interface_parser.hpp"
#include "libs/struct_parser.hpp"
#include <fstream>
class sdkbuilder {
std::string build_dir= "./";
void construct(
const std::vector<std::string> &descr_templ,
const std::vector<std::pair<std::string, std::string>> &templ,
const bool &has_template, const std::string type_obj,
const std::string normal_name, const std::string &body,
const std::string filename );
void construct_hpp(
const std::string filename, const std::string _template,
const std::string type_obj, const std::string &body,
const std::string &normal_name );
std::string generate_interface_body(
const interface_parser *_interface_parser,
const std::string normal_name );
std::string generate_struct_body(
const struct_parser *_struct_parser, const std::string normal_name );
void write_args( std::string &file, std::vector<method>::const_iterator &it );
public:
sdkbuilder(
const std::vector<std::pair<std::string, std::string>>
&interfaces_filenames,
const std::string out_path );
};
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment