Use codegen, updated sir

master
Marko Semet 2019-07-11 15:41:57 +02:00
parent 27c8714130
commit 6f56ffece9
5 changed files with 182 additions and 19 deletions

View File

@ -11,6 +11,8 @@ namespace sirEdit {
extern void doSave(bool blocking=false);
extern std::string getSavePath();
extern std::string getSirPath();
extern std::string getSpec(const sirEdit::data::Tool* tool);
extern void loadFile(Gtk::Window* window, Gtk::FileChooserNative* chooser);
extern void runInGui(std::function<void()> func);

View File

@ -15,33 +15,42 @@ gtkmm = dependency('gtkmm-3.0', version: '>= 3.18')
# Sources of sir
src_sir = [
'sir/BuildInformationFieldDeclarations.cpp',
'sir/CommentFieldDeclarations.cpp',
'sir/CommentTagFieldDeclarations.cpp',
'sir/CustomFieldOptionFieldDeclarations.cpp',
'sir/FieldLikeFieldDeclarations.cpp',
'sir/FilePathFieldDeclarations.cpp',
'sir/HintFieldDeclarations.cpp',
'sir/IdentifierFieldDeclarations.cpp',
'sir/RestrictionFieldDeclarations.cpp',
'sir/ToolFieldDeclarations.cpp',
'sir/ToolTypeCustomizationFieldDeclarations.cpp',
'sir/TypeFieldDeclarations.cpp',
'sir/File.cpp',
'sir/BuildInformationPools.cpp',
'sir/CommentPools.cpp',
'sir/CommentTagPools.cpp',
'sir/CustomFieldOptionPools.cpp',
'sir/FieldLikePools.cpp',
'sir/FilePathPools.cpp',
'sir/HintPools.cpp',
'sir/IdentifierPools.cpp',
'sir/RestrictionPools.cpp',
'sir/ToolPools.cpp',
'sir/ToolTypeCustomizationPools.cpp',
'sir/TypePools.cpp',
'sir/TypesOfBuildInformation.cpp',
'sir/TypesOfComment.cpp',
'sir/TypesOfCommentTag.cpp',
'sir/TypesOfCustomFieldOption.cpp',
'sir/TypesOfFieldLike.cpp',
'sir/TypesOfFilePath.cpp',
'sir/TypesOfHint.cpp',
'sir/TypesOfIdentifier.cpp',
'sir/TypesOfRestriction.cpp',
'sir/TypesOfTool.cpp',
'sir/TypesOfToolTypeCustomization.cpp',
'sir/TypesOfType.cpp'
]
inc_sir = include_directories('sir')

View File

@ -7,15 +7,79 @@ Tool {
string description;
string command;
/**
* build targets associated with this tool
*/
BuildInformation[] buildTargets;
/**
* the map of user types selected by this tool.
* The string can get "u", "r", "w", "d".
*/
map<UserdefinedType, string> selectedUserTypes;
map<UserdefinedType, string> selTypes;
/**
* The set of fields selected by this tool.
* The string can get "u", "r", "w", "c".
*/
map<UserdefinedType, FieldLike, string> selectedFields;
map<UserdefinedType, FieldLike, string> selFields;
/**
* the set of user types selected by this tool
*/
set<UserdefinedType> selectedUserTypes;
/**
* The set of fields selected by this tool.
* The string argument is used to ensure, that selected fields have unique names.
*/
map<UserdefinedType, string, FieldLike> selectedFields;
/* overrides existing annotations */
map<UserdefinedType, ToolTypeCustomization> customTypeAnnotations;
/* overrides existing annotations */
map<FieldLike, ToolTypeCustomization> customFieldAnnotations;
}
/**
* this type is used to allow tools to define their own non-standard set of hints and restrictions
*/
ToolTypeCustomization extends Annotations {}
BuildInformation {
/**
* the output directory passed to the target generator
*/
FilePath output;
/**
* the name of the language to be used. It is explicitly discouraged to use all languages.
* Create different build informations for every language instead, as the output directory should be changed.
*/
string language;
/**
* options are processed as if they were entered in the command line interface
*
* @note options consisting of multiple strings will be stored in multiple strings in this form
*/
string[] options;
}
/**
* a path that can be used in the description of a build process
*/
FilePath {
/**
* true, iff starting from file system root
*/
bool isAbsolut;
/**
* parts of the path that will be assembled into a usable path
*/
string[] parts;
}

View File

@ -11,6 +11,8 @@
#include <functional>
#include <stdexcept>
#include <iostream>
using namespace sir::api;
using namespace sirEdit::data;
using namespace std;
@ -671,9 +673,10 @@ namespace {
// Update types
auto types = new ::skill::api::Map<::sir::UserdefinedType*, ::skill::api::String>();
if(sTool->getSelectedUserTypes() != nullptr)
delete sTool->getSelectedUserTypes();
sTool->setSelectedUserTypes(types);
if(sTool->getSelTypes() != nullptr)
delete sTool->getSelTypes();
sTool->setSelTypes(types);
for(auto& j : i.second.getStatesTypes()) {
switch(get<1>(j.second)) {
case TYPE_STATE::READ:
@ -696,9 +699,9 @@ namespace {
// Update fields
{
auto fields = new ::skill::api::Map<::sir::UserdefinedType*, ::skill::api::Map<::sir::FieldLike*, ::skill::api::String>*>();
if(sTool->getSelectedFields() != nullptr)
delete sTool->getSelectedFields();
sTool->setSelectedFields(fields);
if(sTool->getSelFields() != nullptr)
delete sTool->getSelFields();
sTool->setSelFields(fields);
// Copy field data
for(auto& j : i.second.getStatesFields()) {
@ -736,10 +739,49 @@ namespace {
tmp = fields->find(static_cast<sir::UserdefinedType*>(this->types[const_cast<Type*>(k.first)]));
}
(*(tmp->second))[this->field[const_cast<Field*>(j.first)]] = s;
auto& tmp2 = (*fields)[static_cast<sir::UserdefinedType*>(this->types[const_cast<Type*>(k.first)])];
(*tmp2)[this->field[const_cast<Field*>(j.first)]] = s;
}
}
}
// Update codegen data
{
if(sTool->getSelectedUserTypes() == nullptr)
sTool->setSelectedUserTypes(new skill::api::Set<sir::UserdefinedType*>(0));
if(sTool->getSelectedFields() == nullptr)
sTool->setSelectedFields(new skill::api::Map<sir::UserdefinedType*, skill::api::Map<skill::api::String, sir::FieldLike*>*>());
auto& forCMDType = *(sTool->getSelectedUserTypes());
forCMDType.clear();
auto& forCMDField = *(sTool->getSelectedFields());
forCMDField.clear();
// Bugfix for interfaces
for(auto& j : this->types) {
if(i.second.getTypeTransitiveState(*j.first) < TYPE_STATE::READ)
continue;
auto nothing = []() -> void {};
doBaseType(j.first, nothing, [&i, j]() -> void {
for(auto& k : getFields(*j.first))
i.second.setFieldState(*j.first, k, FIELD_STATE::READ);
}, nothing, nothing, nothing);
}
// Set data
for(auto j : this->types)
if(dynamic_cast<sir::UserdefinedType*>(j.second) != nullptr)
if(i.second.getTypeTransitiveState(*j.first) >= TYPE_STATE::READ) {
forCMDType.insert(dynamic_cast<sir::UserdefinedType*>(j.second));
auto fieldsRef = new skill::api::Map<skill::api::String, sir::FieldLike*>();
forCMDField[dynamic_cast<sir::UserdefinedType*>(j.second)] = fieldsRef;
for(auto& k : listAllFields(*(j.first)))
if(i.second.getFieldTransitiveState(*k) >= FIELD_STATE::READ) {
auto tmp = this->field.find(const_cast<Field*>(k));
if(tmp != this->field.end())
(*fieldsRef)[this->newSirString(j.first->getName())] = tmp->second;
}
}
}
}
this->saveToolData.clear();
this->saveTools.clear();

View File

@ -1,9 +1,11 @@
#include <cstdio>
#include <fstream>
#include <atomic>
#include <fstream>
#include <future>
#include <iostream>
#include <thread>
#include <mutex>
#include <sirEdit/main.hpp>
#include <sirEdit/data/serialize.hpp>
@ -21,12 +23,53 @@ static thread& loader_thread = *_loader_thread;
static Glib::RefPtr<Gio::File> outputFile;
static std::string filePath;
static sirEdit::data::Serializer* ser;
static mutex saveMutex;
std::string sirEdit::getSavePath() {
extern std::string sirEdit::getSavePath() {
return outputFile->get_parent()->get_path();
}
extern std::string sirEdit::getSirPath() {
return filePath;
}
extern std::string sirEdit::getSpec(const sirEdit::data::Tool* tool) {
// Global spec?
bool wasGlobal = false;
if(tool == nullptr) {
wasGlobal = true;
auto* t = new sirEdit::data::Tool("@@ALL@@", "", "");
tool = t;
for(auto& i : ser->getTypes())
for(auto& j : sirEdit::data::getFields(*i))
t->setFieldState(*i, j, sirEdit::data::FIELD_STATE::READ);
ser->addTool(t);
}
// Save
sirEdit::doSave();
void sirEdit::doSave(bool blocking) {
// Call codegen
std::string path = filePath.substr(0, filePath.rfind("/"));
sirEdit::runCodegen({filePath, "-t", tool->getName(), "-b"}, path);
// Read data
string result;
{
auto fileSize = ifstream(path + "/specification.skill", ios::ate | ios::binary).tellg();
result.resize(fileSize);
ifstream in(path + "/specification.skill", ios::binary);
in.read(const_cast<char*>(&(result[0])), fileSize);
}
// Was global spec?
if(wasGlobal) {
ser->removeTool(const_cast<sirEdit::data::Tool*>(tool));
sirEdit::doSave();
}
// Return
return result;
}
extern void sirEdit::doSave(bool blocking) {
// Save function
auto toRunFunc = []() -> void {
char buffer[256];
@ -41,16 +84,19 @@ void sirEdit::doSave(bool blocking) {
};
// TODO: Asyc
ser->prepareSave();
ser->save();
toRunFunc();
{
lock_guard<mutex> __lock__(saveMutex);
ser->prepareSave();
ser->save();
toRunFunc();
}
}
inline void loadFileThread(Gtk::Window* mainWindow, Gtk::Window* popup, Glib::RefPtr<Gio::File> file) {
outputFile = file;
// Create tmpfile
string fileName = tmpnam(nullptr); // TODO: replace tmpnam
string fileName = string(tmpnam(nullptr)) + ".sir";
filePath = fileName;
FILE* output = fopen(fileName.c_str(), "w");
@ -90,19 +136,19 @@ inline void loadFileThread(Gtk::Window* mainWindow, Gtk::Window* popup, Glib::Re
}
});
cv.wait(lock);
}
extern void sirEdit::loadFile(Gtk::Window* window, Gtk::FileChooserNative* chooser) {
// Autosave
new thread([]() -> void {
if(ended)
return;
runInGui([]() -> void {
doSave(false);
sirEdit::runInGui([]() -> void {
sirEdit::doSave(false);
});
sleep(30);
});
}
extern void sirEdit::loadFile(Gtk::Window* window, Gtk::FileChooserNative* chooser) {
// Start loader
auto files = chooser->get_files();
if(files.size() != 1)