added basic support for calling variables and functions from morm::Model objects
This commit is contained in:
165
src/generator.h
165
src/generator.h
@@ -39,15 +39,16 @@
|
||||
#ifndef headerfile_ezc_generator
|
||||
#define headerfile_ezc_generator
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include "blocks.h"
|
||||
#include "pattern.h"
|
||||
#include "functions.h"
|
||||
#include "objects.h"
|
||||
#include "outstreams.h"
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include "expressionparser.h"
|
||||
#include "models.h"
|
||||
|
||||
|
||||
namespace Ezc
|
||||
@@ -74,7 +75,7 @@ public:
|
||||
void SetFunctions(Functions<StreamType> & functions);
|
||||
void SetObjects(Objects<StreamType> & objects);
|
||||
void SetVariables(Vars & variables); // [def] and [let]
|
||||
|
||||
void SetModels(Models & models);
|
||||
|
||||
void SetMax(size_t max_items_, size_t max_for_items_);
|
||||
|
||||
@@ -151,6 +152,7 @@ private:
|
||||
Blocks * pblocks;
|
||||
Functions<StreamType> * pfunctions;
|
||||
Objects<StreamType> * pobjects;
|
||||
Models * pmodels;
|
||||
Vars * pvars;
|
||||
|
||||
// pointer to the output streams map (can be null)
|
||||
@@ -244,6 +246,8 @@ private:
|
||||
typename Functions<StreamType>::UserFunction ** function,
|
||||
Item ** item_block);
|
||||
|
||||
bool FindInModels(const std::wstring & name, morm::Model ** model);
|
||||
|
||||
bool FindInFunctionsAndBlocks(const std::wstring & name,
|
||||
BaseObj<StreamType> ** base_obj,
|
||||
int * method_index,
|
||||
@@ -274,9 +278,9 @@ private:
|
||||
std::vector<Var> & parameters,
|
||||
StreamType & out_stream);
|
||||
|
||||
|
||||
void CallObject(BaseObj<StreamType> * base_obj, int method_index, FunInfo<StreamType> & info);
|
||||
|
||||
void CallModel(morm::Model & model, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream);
|
||||
|
||||
void CallObject(BaseObj<StreamType> * base_obj,
|
||||
int method_index,
|
||||
@@ -306,6 +310,8 @@ private:
|
||||
void TrimWhite(const wchar_t *& start, const wchar_t *& end);
|
||||
void SkipWhite(const wchar_t *& str);
|
||||
size_t StrToSize(const wchar_t * str, const wchar_t ** str_end = 0);
|
||||
void CopyStream(pt::TextStream src_stream, StreamType & dst_stream, bool should_escape);
|
||||
bool ShouldEscapeValue(std::vector<Var> parameters);
|
||||
|
||||
|
||||
void CopyTmpStreamToOutputStreams(Item::Function & fun, StreamType & ezc_out_tmp_stream, StreamType & previous_stream);
|
||||
@@ -351,11 +357,12 @@ private:
|
||||
template<class StreamType>
|
||||
Generator<StreamType>::Generator() : empty_stream()
|
||||
{
|
||||
ppattern = 0;
|
||||
pblocks = 0;
|
||||
pfunctions = 0;
|
||||
pobjects = 0;
|
||||
pvars = 0;
|
||||
ppattern = nullptr;
|
||||
pblocks = nullptr;
|
||||
pfunctions = nullptr;
|
||||
pobjects = nullptr;
|
||||
pvars = nullptr;
|
||||
pmodels = nullptr;
|
||||
|
||||
max_items = 50000;
|
||||
max_for_items = 5000;
|
||||
@@ -390,6 +397,7 @@ Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamT
|
||||
pfunctions = n.pfunctions;
|
||||
pobjects = n.pobjects;
|
||||
pvars = n.pvars;
|
||||
pmodels = n.pmodels;
|
||||
|
||||
max_items = n.max_items;
|
||||
max_for_items = n.max_for_items;
|
||||
@@ -507,6 +515,13 @@ void Generator<StreamType>::SetVariables(Vars & variables)
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::SetModels(Models & models)
|
||||
{
|
||||
pmodels = ⊧
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CanUseCache(bool can_use_cache)
|
||||
{
|
||||
@@ -875,6 +890,28 @@ return false;
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::FindInModels(const std::wstring & name, morm::Model ** model)
|
||||
{
|
||||
*model = nullptr;
|
||||
|
||||
if( pmodels )
|
||||
{
|
||||
morm::Model * m = pmodels->Find(name);
|
||||
|
||||
if( m )
|
||||
{
|
||||
*model = m;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::FindInFunctionsAndBlocks(const std::wstring & name,
|
||||
BaseObj<StreamType> ** base_obj,
|
||||
@@ -1043,6 +1080,99 @@ void Generator<StreamType>::CallObject(BaseObj<StreamType> * base_obj, int metho
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CopyStream(pt::TextStream src_stream, StreamType & dst_stream, bool should_escape)
|
||||
{
|
||||
pt::TextStream::iterator i = src_stream.begin();
|
||||
|
||||
while( i != src_stream.end() )
|
||||
{
|
||||
if( should_escape )
|
||||
{
|
||||
dst_stream << *i;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_stream.write(&(*i), 1);
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
bool Generator<StreamType>::ShouldEscapeValue(std::vector<Var> parameters)
|
||||
{
|
||||
for(Var & var : parameters)
|
||||
{
|
||||
if( !var.is_function )
|
||||
{
|
||||
if( var.str == L"raw" || var.str == L"noescape" )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CallModel(morm::Model & model, std::vector<std::wstring> & fields, std::vector<Var> parameters, StreamType & out_stream, const StreamType & in_stream)
|
||||
{
|
||||
bool should_escape = ShouldEscapeValue(parameters);
|
||||
|
||||
if( fields.empty() )
|
||||
{
|
||||
pt::TextStream str;
|
||||
model.to_text(str, false, false);
|
||||
CopyStream(str, out_stream, should_escape);
|
||||
}
|
||||
else
|
||||
{
|
||||
morm::Model * m = &model;
|
||||
|
||||
for(size_t i=0 ; i<fields.size() ; ++i)
|
||||
{
|
||||
std::wstring & field = fields[i];
|
||||
|
||||
if( i+1 < fields.size() )
|
||||
{
|
||||
m = m->get_field_model(field.c_str(), field.c_str());
|
||||
|
||||
if( !m )
|
||||
{
|
||||
// put some log
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// last field
|
||||
pt::TextStream str;
|
||||
|
||||
if( parameters.empty() )
|
||||
{
|
||||
FunInfo<StreamType> info(out_stream, parameters, empty, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
|
||||
m->put_field_value(field.c_str(), nullptr, info, str, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
FunInfo<StreamType> info(out_stream, parameters, parameters[0].str, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
|
||||
m->put_field_value(field.c_str(), nullptr, info, str, false);
|
||||
}
|
||||
|
||||
CopyStream(str, out_stream, should_escape);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class StreamType>
|
||||
void Generator<StreamType>::CallObject(BaseObj<StreamType> * base_obj,
|
||||
int method_index,
|
||||
@@ -1140,12 +1270,20 @@ typename Functions<StreamType>::UserFunction * fun;
|
||||
Item * item_block;
|
||||
Var * variable;
|
||||
std::vector<Var> parameters;
|
||||
morm::Model * model;
|
||||
|
||||
if( clear_out_stream )
|
||||
ClearStream(out_stream);
|
||||
|
||||
if( !Find(item_fun, fun_name, &base_obj, &method_index, &fun, &item_block, &variable) )
|
||||
return false;
|
||||
if( !fun_name )
|
||||
fun_name = &item_fun.name;
|
||||
|
||||
// add macro
|
||||
if( !FindInModels(*fun_name, &model) )
|
||||
{
|
||||
if( !Find(item_fun, fun_name, &base_obj, &method_index, &fun, &item_block, &variable) )
|
||||
return false;
|
||||
}
|
||||
|
||||
parameters.resize(item_fun.parameters.size());
|
||||
|
||||
@@ -1173,6 +1311,9 @@ std::vector<Var> parameters;
|
||||
}
|
||||
}
|
||||
|
||||
if( model )
|
||||
CallModel(*model, item_fun.fields, parameters, out_stream, in_stream);
|
||||
else
|
||||
if( base_obj )
|
||||
CallObject(base_obj, method_index, parameters, out_stream, in_stream);
|
||||
else
|
||||
|
Reference in New Issue
Block a user