2010-11-22 02:23:32 +01:00
/*
2014-10-17 23:48:11 +02:00
* This file is a part of EZC - - Easy templating in C + + library
* and is distributed under the BSD 3 - Clause licence .
2010-11-22 02:23:32 +01:00
* Author : Tomasz Sowa < t . sowa @ ttmath . org >
*/
/*
2022-04-12 19:10:10 +02:00
* Copyright ( c ) 2007 - 2022 , Tomasz Sowa
2010-11-22 02:23:32 +01:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions are met :
*
* * Redistributions of source code must retain the above copyright notice ,
* this list of conditions and the following disclaimer .
*
* * Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* * Neither the name Tomasz Sowa nor the names of contributors to this
* project may be used to endorse or promote products derived
* from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
* AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
* CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
* INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
* CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE .
*/
# ifndef headerfile_ezc_generator
# define headerfile_ezc_generator
2021-05-31 18:37:09 +02:00
# include <sstream>
# include <fstream>
# include <vector>
2014-10-17 23:36:55 +02:00
# include "blocks.h"
2010-11-22 02:23:32 +01:00
# include "pattern.h"
# include "functions.h"
2015-06-14 20:20:00 +02:00
# include "objects.h"
2015-11-12 10:53:20 +01:00
# include "outstreams.h"
2018-10-30 00:50:10 +01:00
# include "expressionparser.h"
2021-06-19 20:18:30 +02:00
# include "log/log.h"
2021-06-20 16:54:55 +02:00
# include "utf8/utf8.h"
2021-10-20 08:23:45 +02:00
# include "vars.h"
2021-06-20 16:54:55 +02:00
2011-01-26 13:42:49 +01:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
# include "model.h"
# endif
2010-11-22 02:23:32 +01:00
namespace Ezc
{
2012-02-27 18:39:46 +01:00
2010-11-25 02:55:32 +01:00
/*
StreamType
2010-11-25 23:39:58 +01:00
we use only method write ( const wchar_t * str , size_t len ) from the stream
2010-11-25 02:55:32 +01:00
*/
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream = false , bool is_autoescape_stream = false >
2010-11-22 02:23:32 +01:00
class Generator
{
public :
Generator ( ) ;
2011-01-26 13:42:49 +01:00
Generator ( const Generator & n ) ;
Generator & operator = ( const Generator & n ) ;
~ Generator ( ) ;
2014-10-17 23:36:55 +02:00
void SetPattern ( Pattern & pattern ) ;
2021-10-20 08:23:45 +02:00
void SetVariables ( Vars < StreamType > & variables ) ;
2021-06-16 14:16:49 +02:00
2021-06-19 20:18:30 +02:00
void SetLogger ( pt : : Log & logger ) ;
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-22 15:44:37 +01:00
//void SetModels(Models & models);
2021-06-16 14:16:49 +02:00
# endif
2010-11-22 02:23:32 +01:00
2012-02-24 13:04:36 +01:00
void SetMax ( size_t max_items_ , size_t max_for_items_ ) ;
2010-11-22 02:23:32 +01:00
// recognizing some special characters in text patterns (item_text in Patterns)
// \r will be a carriage return (13)
// \n will be a new line (10)
// \t will be a tabulator (9)
// \s will be a space
// \\ will be one '\'
2010-11-25 02:55:32 +01:00
// if the second character is different from those shown above the first slash will be printed
// so "\x" gives "\x"
2010-11-22 02:23:32 +01:00
// default: false
void RecognizeSpecialChars ( bool spec ) ;
// trimming white characters (at the beginning and at the end of an item_text)
// (special char \s if enabled is not treated as a white character here)
// default: false
void TrimWhite ( bool trim ) ;
// skipping new line characters (from the whole string in an item_text)
// but you can use a new line character written as "\n" (if special chars are turn on)
// default: false
void SkipNewLine ( bool skip ) ;
2011-01-26 13:42:49 +01:00
// default: 20
void SetMaxFilters ( size_t new_len ) ;
2012-02-27 18:39:46 +01:00
// default stack size: 300
void SetStackSize ( size_t new_stack_size ) ;
2014-10-19 23:09:34 +02:00
// set whether or not we can use variables: [def ...] statement
// true by default
void CanUseVars ( bool can_use_variables ) ;
2018-10-30 00:50:10 +01:00
void SetProgramMode ( bool program_mode ) ;
void SetExpressionParser ( ExpressionParser * expression_parser ) ;
2010-11-25 23:39:58 +01:00
// the main methods for generating
2015-11-12 10:53:20 +01:00
void Generate ( StreamType & out ) ;
2021-07-12 23:00:11 +02:00
void Generate ( StreamType & out , OutStreams < StreamType , is_pikotools_stream > & out_streams ) ;
void Generate ( OutStreams < StreamType , is_pikotools_stream > & out_streams ) ;
2015-11-12 10:53:20 +01:00
2010-11-25 23:39:58 +01:00
2010-11-22 02:23:32 +01:00
private :
2014-10-28 18:46:24 +01:00
2021-11-05 09:34:05 +01:00
struct FindHelperOld
2021-06-16 14:16:49 +02:00
{
2021-10-20 08:23:45 +02:00
//const std::wstring * fun_name;
//BaseObj<StreamType> * base_obj;
//int method_index;
2021-06-16 14:16:49 +02:00
2021-10-20 08:23:45 +02:00
//typename Functions<StreamType>::UserFunction * function;
//Item * item_block;
2022-04-12 19:10:10 +02:00
2021-10-20 08:23:45 +02:00
Var < StreamType > * variable ;
2021-06-16 14:16:49 +02:00
2021-06-19 20:18:30 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-10-27 14:23:48 +02:00
Var < StreamType > * wrapper ;
2021-07-01 23:21:20 +02:00
size_t field_index ;
2021-06-19 20:18:30 +02:00
# endif
2021-06-16 14:16:49 +02:00
2022-04-12 19:10:10 +02:00
2021-11-05 09:34:05 +01:00
FindHelperOld ( )
2021-06-16 14:16:49 +02:00
{
2021-10-20 08:23:45 +02:00
//fun_name = nullptr;
2021-06-19 20:18:30 +02:00
2021-10-20 08:23:45 +02:00
//base_obj = nullptr;
//method_index = -1;
//function = nullptr;
//item_block = nullptr;
2021-06-16 14:16:49 +02:00
variable = nullptr ;
2021-06-19 20:18:30 +02:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-07-01 23:21:20 +02:00
wrapper = nullptr ;
2021-06-16 14:16:49 +02:00
field_index = 0 ;
2021-07-01 23:21:20 +02:00
# endif
2021-06-16 14:16:49 +02:00
}
} ;
2021-11-05 09:34:05 +01:00
// RENAMEME
struct FindHelper
{
const std : : wstring & name ;
std : : vector < std : : wstring > & fields ;
size_t field_index ;
std : : vector < Var < StreamType > > & parameters ;
2021-11-06 19:07:39 +01:00
Var < StreamType > * input ;
Var < StreamType > * result ;
2021-11-05 09:34:05 +01:00
bool found ;
const std : : wstring * previous_name ;
2021-11-05 22:23:22 +01:00
size_t nested_calls ;
2021-11-08 00:41:36 +01:00
Var < StreamType > * current_var ;
Var < StreamType > * previous_var ;
Var < StreamType > * previous_result ;
2021-11-05 09:34:05 +01:00
2021-11-06 19:07:39 +01:00
FindHelper (
const std : : wstring & name ,
std : : vector < std : : wstring > & fields ,
std : : vector < Var < StreamType > > & parameters
) : name ( name ) , fields ( fields ) , parameters ( parameters )
2021-11-05 09:34:05 +01:00
{
field_index = 0 ;
found = false ;
previous_name = nullptr ;
2021-11-05 22:23:22 +01:00
nested_calls = 0 ;
2021-11-06 19:07:39 +01:00
input = nullptr ;
result = nullptr ;
2021-11-08 00:41:36 +01:00
current_var = nullptr ;
previous_var = nullptr ;
previous_result = nullptr ;
2021-11-05 09:34:05 +01:00
}
2021-11-24 13:19:27 +01:00
// rename me to current_field()
2021-11-05 09:34:05 +01:00
const std : : wstring & current_name ( )
{
return ( field_index = = 0 ) ? name : fields [ field_index - 1 ] ;
}
2021-11-24 13:19:27 +01:00
const std : : wstring & next_field ( )
{
return fields [ field_index ] ;
}
2021-11-05 09:34:05 +01:00
bool is_last_field ( )
{
return field_index = = fields . size ( ) ;
}
2021-11-24 13:19:27 +01:00
bool is_next_field ( )
{
return field_index < fields . size ( ) ;
}
2021-11-05 09:34:05 +01:00
} ;
2014-10-17 23:36:55 +02:00
struct BlockStack
{
2021-10-20 08:23:45 +02:00
std : : vector < Var < StreamType > > args ;
2014-10-17 23:36:55 +02:00
StreamType * out_stream ;
2014-10-28 18:46:24 +01:00
bool was_return ;
2014-10-17 23:36:55 +02:00
} ;
std : : vector < BlockStack > block_stack_tab ;
size_t block_stack_index ;
size_t block_stack_size ;
2015-11-12 10:53:20 +01:00
// current output stream (can be null)
// at the beginning it is pointing to the main stream (to the StreamType argument passsed to Generate method)
2010-11-22 02:23:32 +01:00
StreamType * output_stream ;
2014-10-17 23:36:55 +02:00
Pattern * ppattern ;
2021-10-20 08:23:45 +02:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-22 15:44:37 +01:00
//Models * pmodels;
2021-06-16 14:16:49 +02:00
# endif
2021-10-20 08:23:45 +02:00
Vars < StreamType > * pvars ;
2021-06-19 20:18:30 +02:00
pt : : Log * plog ;
2013-11-07 11:16:10 +01:00
2015-11-12 10:53:20 +01:00
// pointer to the output streams map (can be null)
2021-05-28 16:10:16 +02:00
// output stream will be created when [ezc frame "stream_name"] statement is found
2021-07-12 23:00:11 +02:00
OutStreams < StreamType , is_pikotools_stream > * output_frames_streams ;
2013-11-07 11:16:10 +01:00
2010-11-22 02:23:32 +01:00
// temporary error messages
std : : wstring temp_msg ;
bool break_generating ;
2012-02-24 13:04:36 +01:00
size_t current_item ;
size_t max_items ;
size_t max_for_items ;
2010-11-22 02:23:32 +01:00
bool special_chars ;
bool trim_white ;
bool skip_new_line ;
2012-02-27 18:39:46 +01:00
2021-05-28 16:10:16 +02:00
size_t ezc_frames_stack_index ;
size_t ezc_frames_stack_size ;
2015-11-12 10:53:20 +01:00
2012-02-27 18:39:46 +01:00
size_t stack_index ;
size_t stack_size ;
2011-01-26 13:42:49 +01:00
size_t filter_index ;
size_t filter_size ;
// we have to use a pointers table because standard streams such
// as std::wostringstream are not copyable
std : : vector < StreamType * > filter_tab ;
2021-05-28 16:10:16 +02:00
std : : vector < StreamType * > ezc_frame_stack_tab ;
2021-11-06 19:20:11 +01:00
StreamType empty_stream ;
2011-01-26 13:42:49 +01:00
2014-11-02 18:26:56 +01:00
// temporary streams used in [if..] [for...] or [def ...]
2013-11-07 11:16:10 +01:00
// or if output_stream is null and an ezc function should be called
2021-08-29 20:35:15 +02:00
//StreamType stream_temp1, stream_temp_define;
//StreamType stream_temp_define;
2011-01-26 13:42:49 +01:00
2011-04-26 19:17:06 +02:00
// last result from a user function (FunInfo::res)
2021-08-29 20:35:15 +02:00
//bool last_res;
2010-11-22 02:23:32 +01:00
2011-04-26 19:17:06 +02:00
// true if this Generator is working now
bool is_generator_working ;
2012-02-24 13:04:36 +01:00
// true if the Generator is working with [for ...], [if ...] etc.
2012-01-17 23:57:06 +01:00
bool is_generating_for ;
2012-02-24 13:04:36 +01:00
bool is_generating_if ;
2021-07-02 20:23:20 +02:00
bool is_generating_if_def ;
bool is_generating_if_not_def ;
2012-02-24 13:04:36 +01:00
bool is_generating_normal ;
bool is_generating_filter ;
2012-01-17 23:57:06 +01:00
2011-04-26 19:17:06 +02:00
// an empty string for FunInfo objects
2010-11-22 02:23:32 +01:00
// when there is no any parameters
2021-08-29 20:35:15 +02:00
//const std::wstring empty;
2010-11-22 02:23:32 +01:00
2011-04-26 19:17:06 +02:00
// a stack for [for] statements
2012-02-27 18:39:46 +01:00
std : : vector < Stack > stack_tab ;
2011-01-15 00:59:30 +01:00
2014-10-19 23:09:34 +02:00
bool can_use_vars ;
2018-10-30 00:50:10 +01:00
bool program_mode ;
2021-11-05 22:23:22 +01:00
size_t max_nested_calls ;
2018-10-30 00:50:10 +01:00
ExpressionParser * expression_parser ;
2015-11-12 10:53:20 +01:00
void ResizeStreamStack ( std : : vector < StreamType * > & stream_tab , size_t stream_tab_max_size ) ;
2011-01-26 13:42:49 +01:00
void ResizeFilterTab ( ) ;
2012-02-27 18:39:46 +01:00
void ResizeStack ( ) ;
2014-10-17 23:36:55 +02:00
void ResizeBlockStack ( ) ;
2021-05-28 16:10:16 +02:00
void ResizeEzcFrameStack ( ) ;
2014-10-17 23:36:55 +02:00
2015-11-12 10:53:20 +01:00
void ClearStreamStack ( std : : vector < StreamType * > & stream_tab ) ;
2011-01-26 13:42:49 +01:00
void ClearFilterTab ( ) ;
2014-10-17 23:36:55 +02:00
void ClearForStack ( ) ;
2014-10-21 09:21:20 +02:00
void ClearBlockStack ( ) ;
2021-05-28 16:10:16 +02:00
void ClearEzcFrameTab ( ) ;
2014-10-21 09:21:20 +02:00
2011-01-26 13:42:49 +01:00
void ClearStream ( StreamType & str ) ;
2021-06-20 16:54:55 +02:00
void CopyStreamToString ( StreamType & src_stream , std : : wstring & dst_string ) ;
void CopyStream ( StreamType & src_stream , StreamType & dst_stream ) ;
void CopyStream ( pt : : WTextStream & src_stream , StreamType & dst_stream , bool should_escape ) ;
2012-02-27 18:39:46 +01:00
void RemoveStackFunData ( Stack & sitem ) ;
2011-01-26 13:42:49 +01:00
2015-03-08 03:31:21 +01:00
bool ConvertToBool ( const std : : wstring & str ) ;
2011-04-26 19:17:06 +02:00
template < class CharType >
CharType ToLower ( CharType c ) ;
2021-07-02 20:23:20 +02:00
bool IsTestingFunctionExistence ( ) ;
2015-06-14 20:20:00 +02:00
2021-11-05 09:34:05 +01:00
bool CheckBlockArgument ( int arg_index , FindHelperOld & find_helper ) ;
2015-06-14 20:20:00 +02:00
2011-04-26 19:17:06 +02:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-05 09:34:05 +01:00
//bool FindInModels(FindHelperOld & find_helper);
2021-06-16 14:16:49 +02:00
# endif
2021-05-31 18:37:09 +02:00
2021-08-29 20:55:15 +02:00
void PrepareEnvStruct ( Env < StreamType > & info ) ;
2021-07-02 20:23:20 +02:00
2021-08-29 20:55:15 +02:00
void CallFunction ( typename Functions < StreamType > : : UserFunction & function , Env < StreamType > & info ) ;
2014-10-17 23:36:55 +02:00
2021-11-05 09:34:05 +01:00
void CallFunction ( typename Functions < StreamType > : : UserFunction & function , FindHelper & find_helper ) ;
2014-10-17 23:36:55 +02:00
bool CallBlock ( Item & item_block ,
2021-10-20 08:23:45 +02:00
Var < StreamType > & result ,
std : : vector < Var < StreamType > > & parameters ) ;
2015-06-14 20:20:00 +02:00
2021-11-05 09:34:05 +01:00
void PrintDate ( pt : : Date & date , FindHelper & find_helper ) ;
2021-10-27 14:23:48 +02:00
//bool PrintDatePart(pt::Date & date, const std::wstring & field, std::vector<Var<StreamType>> & parameters, Var<StreamType> & result);
2021-07-01 23:21:20 +02:00
2021-10-27 14:23:48 +02:00
//bool CallDate(pt::Date & date, const std::wstring & name, std::vector<std::wstring> & fields, size_t & field_index, std::vector<Var<StreamType>> & parameters, Var<StreamType> & result);
2021-06-25 16:16:30 +02:00
2021-11-05 09:34:05 +01:00
void PrintLastSpaceField ( pt : : Space & space , FindHelper & find_helper ) ;
2021-11-21 21:08:06 +01:00
//void CallSpaceObjectForLastField(pt::Space & space, FindHelper & find_helper);
2021-10-25 21:33:21 +02:00
//pt::Space * CallSpaceObjectForMiddleField(const std::wstring & root_space_name, std::vector<std::wstring> & fields, size_t field_index, pt::Space * space);
2021-06-25 16:16:30 +02:00
2021-11-05 09:34:05 +01:00
void CallSpaceTableForLastField ( morm : : SpaceWrapper & space_wrapper , pt : : Space & space , FindHelper & find_helper , size_t model_wrapper_space_table_index ) ;
2021-06-25 16:16:30 +02:00
2021-11-05 09:34:05 +01:00
pt : : Space * CallSpaceTableForMiddleField ( morm : : SpaceWrapper & space_wrapper , pt : : Space & space , FindHelper & find_helper , size_t model_wrapper_space_table_index ) ;
2021-06-25 16:16:30 +02:00
2021-11-24 13:19:27 +01:00
bool CallSpaceWrapper ( morm : : SpaceWrapper & space_wrapper , FindHelper & find_helper ) ;
2021-11-23 19:40:52 +01:00
bool CallSpace ( pt : : Space & root_space , FindHelper & find_helper ) ;
2021-06-22 18:01:47 +02:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-05 09:34:05 +01:00
bool CallModelField ( morm : : Model & model , FindHelper & find_helper ) ;
2021-10-27 14:23:48 +02:00
// bool CallModel(morm::Model & model, const std::wstring & name, std::vector<std::wstring> & fields, size_t field_index,
// std::vector<Var<StreamType>> & parameters, Var<StreamType> & result);
2021-11-05 09:34:05 +01:00
// void FindLastModelWrapper(FindHelperOld & find_helper, std::vector<std::wstring> & fields);
// bool CallWrapper(FindHelperOld & find_helper, std::vector<std::wstring> & fields, Var<StreamType> & result, std::vector<Var<StreamType>> & parameters, const StreamType & in_stream);
2015-06-14 20:20:00 +02:00
2021-10-20 08:23:45 +02:00
# endif
2015-06-14 20:20:00 +02:00
2021-10-25 21:33:21 +02:00
Var < StreamType > * FindInScope ( const std : : wstring & name ) ;
2021-11-05 22:23:22 +01:00
void FindVariable ( FindHelper & find_helper ) ;
void EvaluateVariable ( FindHelper & find_helper ) ;
2021-11-24 13:19:27 +01:00
bool EvaluateModel ( FindHelper & find_helper ) ;
bool EvaluateModelWrapper ( FindHelper & find_helper ) ;
2021-11-05 22:23:22 +01:00
void EvaluateFunction ( typename Var < StreamType > : : UserFunction user_function , FindHelper & find_helper ) ;
2021-10-25 21:33:21 +02:00
2021-11-05 09:34:05 +01:00
// bool CallVariable(FindHelper & findxxx
// const std::wstring & name,
// std::vector<std::wstring> & fields,
// size_t & field_index,
// Var<StreamType> & result,
// std::vector<Var<StreamType>> & parameters
// );
2015-06-14 20:20:00 +02:00
2021-10-20 08:23:45 +02:00
2014-10-17 23:36:55 +02:00
bool Call ( Item : : Function & item_fun ,
2021-08-29 20:35:15 +02:00
const std : : wstring * fun_name ,
2021-10-20 08:23:45 +02:00
Var < StreamType > & result ,
2021-11-06 19:20:11 +01:00
StreamType & in_stream ) ;
2014-10-17 23:36:55 +02:00
2021-10-20 08:23:45 +02:00
bool Call ( Item : : Function & item_fun , Var < StreamType > & result ) ;
2011-01-26 13:42:49 +01:00
2010-11-22 02:23:32 +01:00
wchar_t CreateSpecialChar ( wchar_t c ) ;
2010-11-25 02:55:32 +01:00
const wchar_t * PrintSpecialChar ( const wchar_t * start , const wchar_t * end ) ;
2010-11-22 02:23:32 +01:00
void PrintSpecialText ( const wchar_t * start , const wchar_t * end ) ;
void PrintNormalText ( const wchar_t * start , const wchar_t * end ) ;
2014-10-11 21:56:48 +02:00
bool IsWhite ( wchar_t c ) ;
2010-11-22 02:23:32 +01:00
void TrimWhite ( const wchar_t * & start , const wchar_t * & end ) ;
void SkipWhite ( const wchar_t * & str ) ;
2013-11-07 11:16:10 +01:00
size_t StrToSize ( const wchar_t * str , const wchar_t * * str_end = 0 ) ;
2021-06-27 22:42:00 +02:00
2021-10-20 08:23:45 +02:00
bool HasParam ( std : : vector < Var < StreamType > > & parameters , const wchar_t * param1 , const wchar_t * param2 = nullptr ) ;
bool ShouldMakeSpaceDump ( std : : vector < Var < StreamType > > & parameters ) ;
bool ShouldMakeJsonDump ( std : : vector < Var < StreamType > > & parameters ) ;
bool IsPrettyPrint ( std : : vector < Var < StreamType > > & parameters ) ;
2021-06-22 18:01:47 +02:00
2021-11-05 09:34:05 +01:00
void DumpSpaceIfNeeded ( pt : : Space & space , FindHelper & find_helper ) ;
2021-10-20 08:23:45 +02:00
void DumpModelIfNeeded ( morm : : Model & model , Var < StreamType > & result , std : : vector < Var < StreamType > > & parameters ) ;
2010-11-22 02:23:32 +01:00
2013-11-07 11:16:10 +01:00
2015-11-12 10:53:20 +01:00
void CopyTmpStreamToOutputStreams ( Item : : Function & fun , StreamType & ezc_out_tmp_stream , StreamType & previous_stream ) ;
2021-06-19 20:18:30 +02:00
2021-06-25 16:16:30 +02:00
void CreateMsg ( const wchar_t * type , const std : : wstring & model_name , std : : vector < std : : wstring > & fields , size_t how_many_fields_print ,
const wchar_t * arg = nullptr , const wchar_t * arg2 = nullptr , const wchar_t * arg3 = nullptr ) ;
2021-06-19 20:18:30 +02:00
void CreateMsg ( const wchar_t * type , const std : : wstring & model_name , std : : vector < std : : wstring > & fields ,
const wchar_t * arg = nullptr , const wchar_t * arg2 = nullptr , const wchar_t * arg3 = nullptr ) ;
void CreateMsg ( const wchar_t * type , const wchar_t * arg = nullptr ) ;
2010-11-25 23:39:58 +01:00
void CreateMsg ( const std : : wstring & type , const std : : wstring & arg ) ;
void CreateMsg ( const std : : wstring & type ) ;
2021-06-19 20:18:30 +02:00
2012-02-27 18:39:46 +01:00
bool LimitAchieved ( ) ;
2010-11-22 02:23:32 +01:00
2018-10-30 00:50:10 +01:00
void EvaluateProgramNode ( Item & item ) ;
2010-11-22 02:23:32 +01:00
void MakeTextIf_go ( Item & item , bool result ) ;
void MakeTextIf ( Item & item ) ;
2021-07-02 20:23:20 +02:00
void MakeTextIfDef ( Item & item ) ;
void MakeTextIfNotDef ( Item & item ) ;
2010-11-22 02:23:32 +01:00
void MakeTextFor ( Item & item ) ;
void MakeItemText ( Item & item ) ;
void MakeTextContainer ( Item & item ) ;
2021-06-20 16:54:55 +02:00
void MakeTextFunction ( Item & item ) ;
2021-10-20 08:23:45 +02:00
void MakeTextDefine ( Item & item , Var < StreamType > & var ) ;
2010-11-22 02:23:32 +01:00
void MakeTextDefine ( Item & item ) ;
2021-05-23 10:02:51 +02:00
void MakeTextDefineIfNotSet ( Item & item ) ;
2021-10-20 08:23:45 +02:00
void MakeTextLet ( Item & item , Var < StreamType > & var ) ;
2021-05-23 10:02:51 +02:00
void MakeTextLet ( Item & item ) ;
void MakeTextLetIfNotSet ( Item & item ) ;
2011-01-26 13:42:49 +01:00
void MakeTextFilter ( Item & item ) ;
2013-11-07 11:16:10 +01:00
void MakeTextEzc ( Item & item ) ;
2014-10-28 18:46:24 +01:00
void MakeTextReturn ( Item & item ) ;
2010-11-22 02:23:32 +01:00
void MakeText ( Item & item ) ;
2021-05-28 16:10:16 +02:00
void MakeEzcFrame ( Item & item ) ;
2013-11-07 11:16:10 +01:00
2014-10-17 23:36:55 +02:00
void Generate ( ) ;
2013-11-07 11:16:10 +01:00
2011-01-26 13:42:49 +01:00
2010-11-22 02:23:32 +01:00
} ; // class Generator
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Generator ( ) : empty_stream ( )
2010-11-22 02:23:32 +01:00
{
2021-05-31 18:37:09 +02:00
ppattern = nullptr ;
pvars = nullptr ;
2021-06-19 20:18:30 +02:00
plog = nullptr ;
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-22 15:44:37 +01:00
//pmodels = nullptr;
2021-06-16 14:16:49 +02:00
# endif
2010-11-22 02:23:32 +01:00
max_items = 50000 ;
max_for_items = 5000 ;
2011-01-26 13:42:49 +01:00
filter_size = 20 ;
2010-11-22 02:23:32 +01:00
special_chars = false ;
trim_white = false ;
skip_new_line = false ;
2011-04-26 19:17:06 +02:00
is_generator_working = false ;
2012-02-27 18:39:46 +01:00
stack_size = 300 ;
2014-10-17 23:36:55 +02:00
block_stack_size = 64 ;
2021-05-28 16:10:16 +02:00
ezc_frames_stack_size = 16 ;
2014-10-19 23:09:34 +02:00
can_use_vars = true ;
2018-10-30 00:50:10 +01:00
expression_parser = nullptr ;
2018-11-01 22:52:33 +01:00
program_mode = false ;
2021-11-05 22:23:22 +01:00
max_nested_calls = 64 ;
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Generator ( const Generator < StreamType , is_pikotools_stream , is_autoescape_stream > & n )
2011-01-26 13:42:49 +01:00
{
operator = ( n ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
Generator < StreamType , is_pikotools_stream , is_autoescape_stream > &
Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : operator = ( const Generator < StreamType , is_pikotools_stream , is_autoescape_stream > & n )
2011-01-26 13:42:49 +01:00
{
2014-10-17 23:36:55 +02:00
ppattern = n . ppattern ;
2021-05-23 10:02:51 +02:00
pvars = n . pvars ;
2021-06-19 20:18:30 +02:00
plog = n . plog ;
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-22 15:44:37 +01:00
//pmodels = n.pmodels;
2021-06-16 14:16:49 +02:00
# endif
2014-10-17 23:36:55 +02:00
2012-02-27 18:39:46 +01:00
max_items = n . max_items ;
max_for_items = n . max_for_items ;
special_chars = n . special_chars ;
trim_white = n . trim_white ;
skip_new_line = n . skip_new_line ;
2014-10-19 23:09:34 +02:00
can_use_vars = n . can_use_vars ;
2012-02-27 18:39:46 +01:00
2014-10-17 23:36:55 +02:00
// filter, stack and block_stack will be auto resized when calling Generate() method
filter_size = n . filter_size ;
stack_size = n . stack_size ;
block_stack_size = n . block_stack_size ;
2021-05-28 16:10:16 +02:00
ezc_frames_stack_size = n . ezc_frames_stack_size ;
2018-10-30 00:50:10 +01:00
expression_parser = n . expression_parser ;
2018-11-01 22:52:33 +01:00
program_mode = n . program_mode ;
2021-11-05 22:23:22 +01:00
max_nested_calls = n . max_nested_calls ;
2014-10-17 23:36:55 +02:00
2014-10-19 23:09:34 +02:00
// vars doesn't have to be copied
2012-02-27 18:39:46 +01:00
2011-01-26 13:42:49 +01:00
// don't copy filter tab
2012-02-27 18:39:46 +01:00
// don't copy stack
2021-05-28 16:10:16 +02:00
// don't copy ezc_frame_stack_tab
// don't copy output_stream and output_frames_streams
2011-01-26 13:42:49 +01:00
2012-02-25 04:29:44 +01:00
// !! CHECK ME
// may copying should be denied when generator is working?
2011-04-26 19:17:06 +02:00
// don't copy 'is_generator_working' flag
is_generator_working = false ;
2011-01-26 13:42:49 +01:00
return * this ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ~ Generator ( )
2011-01-26 13:42:49 +01:00
{
ClearFilterTab ( ) ;
2012-02-24 13:04:36 +01:00
ClearForStack ( ) ;
2014-10-21 09:21:20 +02:00
ClearBlockStack ( ) ;
2021-05-28 16:10:16 +02:00
ClearEzcFrameTab ( ) ;
2011-01-26 13:42:49 +01:00
}
2014-10-19 07:42:25 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetPattern ( Pattern & pattern )
2014-10-17 23:36:55 +02:00
{
ppattern = & pattern ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetVariables ( Vars < StreamType > & variables )
2021-05-23 10:02:51 +02:00
{
pvars = & variables ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetLogger ( pt : : Log & logger )
2021-06-19 20:18:30 +02:00
{
plog = & logger ;
}
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-11-22 15:44:37 +01:00
//template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
//void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::SetModels(Models & models)
//{
// pmodels = ⊧
//}
2021-06-16 14:16:49 +02:00
# endif
2021-05-31 18:37:09 +02:00
2014-10-19 23:09:34 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CanUseVars ( bool can_use_variables )
2014-10-19 23:09:34 +02:00
{
can_use_vars = can_use_variables ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetProgramMode ( bool set_program_mode )
2018-10-30 00:50:10 +01:00
{
this - > program_mode = set_program_mode ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetExpressionParser ( ExpressionParser * expression_parser )
2018-10-30 00:50:10 +01:00
{
this - > expression_parser = expression_parser ;
}
2014-10-19 23:09:34 +02:00
2014-10-17 23:36:55 +02:00
2015-11-12 10:53:20 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ResizeStack ( )
2011-01-26 13:42:49 +01:00
{
2015-11-12 10:53:20 +01:00
if ( stack_tab . size ( ) ! = stack_size )
2011-01-26 13:42:49 +01:00
{
2015-11-12 10:53:20 +01:00
if ( stack_tab . size ( ) > stack_size )
2011-01-26 13:42:49 +01:00
{
2015-11-12 10:53:20 +01:00
for ( size_t i = stack_size ; i < stack_tab . size ( ) ; + + i )
RemoveStackFunData ( stack_tab [ i ] ) ;
}
stack_tab . resize ( stack_size ) ;
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ResizeStreamStack ( std : : vector < StreamType * > & stream_tab , size_t stream_tab_max_size )
2015-11-12 10:53:20 +01:00
{
if ( stream_tab . size ( ) ! = stream_tab_max_size )
{
if ( stream_tab . size ( ) < stream_tab_max_size )
{
size_t i = stream_tab . size ( ) ;
stream_tab . resize ( stream_tab_max_size ) ;
for ( ; i < stream_tab . size ( ) ; + + i )
stream_tab [ i ] = new StreamType ( ) ;
2011-01-26 13:42:49 +01:00
}
else
{
2015-11-12 10:53:20 +01:00
for ( size_t i = stream_tab_max_size ; i < stream_tab . size ( ) ; + + i )
delete stream_tab [ i ] ;
2011-01-26 13:42:49 +01:00
2015-11-12 10:53:20 +01:00
stream_tab . resize ( stream_tab_max_size ) ;
2011-01-26 13:42:49 +01:00
}
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ResizeFilterTab ( )
2012-02-27 18:39:46 +01:00
{
2015-11-12 10:53:20 +01:00
ResizeStreamStack ( filter_tab , filter_size ) ;
}
2012-02-27 18:39:46 +01:00
2015-11-12 10:53:20 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ResizeEzcFrameStack ( )
2015-11-12 10:53:20 +01:00
{
2021-05-28 16:10:16 +02:00
ResizeStreamStack ( ezc_frame_stack_tab , ezc_frames_stack_size ) ;
2012-02-27 18:39:46 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ResizeBlockStack ( )
2014-10-17 23:36:55 +02:00
{
if ( block_stack_tab . size ( ) ! = block_stack_size )
{
if ( block_stack_tab . size ( ) < block_stack_size )
{
size_t i = block_stack_tab . size ( ) ;
block_stack_tab . resize ( block_stack_size ) ;
for ( ; i < block_stack_tab . size ( ) ; + + i )
block_stack_tab [ i ] . out_stream = new StreamType ( ) ;
}
else
{
for ( size_t i = block_stack_size ; i < block_stack_tab . size ( ) ; + + i )
delete block_stack_tab [ i ] . out_stream ;
block_stack_tab . resize ( block_stack_size ) ;
}
}
}
2015-11-12 10:53:20 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ClearStreamStack ( std : : vector < StreamType * > & stream_tab )
2015-11-12 10:53:20 +01:00
{
for ( size_t i = 0 ; i < stream_tab . size ( ) ; + + i )
delete stream_tab [ i ] ;
stream_tab . clear ( ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ClearFilterTab ( )
2011-01-26 13:42:49 +01:00
{
2015-11-12 10:53:20 +01:00
ClearStreamStack ( filter_tab ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ClearEzcFrameTab ( )
2015-11-12 10:53:20 +01:00
{
2021-05-28 16:10:16 +02:00
ClearStreamStack ( ezc_frame_stack_tab ) ;
2011-01-26 13:42:49 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ClearBlockStack ( )
2014-10-21 09:21:20 +02:00
{
for ( size_t i = 0 ; i < block_stack_tab . size ( ) ; + + i )
delete block_stack_tab [ i ] . out_stream ;
block_stack_tab . clear ( ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ClearForStack ( )
2012-02-24 13:04:36 +01:00
{
for ( size_t i = 0 ; i < stack_tab . size ( ) ; + + i )
2012-02-25 04:29:44 +01:00
RemoveStackFunData ( stack_tab [ i ] ) ;
2012-02-24 13:04:36 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ClearStream ( StreamType & str )
2011-01-26 13:42:49 +01:00
{
2021-07-12 23:00:11 +02:00
if constexpr ( is_pikotools_stream )
{
2021-06-20 16:54:55 +02:00
str . clear ( ) ;
2021-07-12 23:00:11 +02:00
}
else
{
2011-01-26 13:42:49 +01:00
str . str ( L " " ) ;
2021-07-12 23:00:11 +02:00
}
2011-01-26 13:42:49 +01:00
}
2010-11-22 02:23:32 +01:00
2021-06-20 16:54:55 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CopyStreamToString ( StreamType & src_stream , std : : wstring & dst_string )
2021-06-20 16:54:55 +02:00
{
if constexpr ( sizeof ( wchar_t ) = = sizeof ( typename StreamType : : char_type ) )
{
2021-07-12 23:00:11 +02:00
if constexpr ( is_pikotools_stream )
{
2021-06-20 16:54:55 +02:00
src_stream . to_str ( dst_string ) ;
2021-07-12 23:00:11 +02:00
}
else
{
2021-06-20 16:54:55 +02:00
dst_string = src_stream . str ( ) ;
2021-07-12 23:00:11 +02:00
}
2021-06-20 16:54:55 +02:00
}
else
{
2021-07-12 23:00:11 +02:00
if constexpr ( is_pikotools_stream )
{
2021-06-20 16:54:55 +02:00
src_stream . to_str ( dst_string ) ;
2021-07-12 23:00:11 +02:00
}
else
{
2021-06-20 16:54:55 +02:00
std : : string tmp = src_stream . str ( ) ;
pt : : utf8_to_wide ( tmp , dst_string ) ;
2021-07-12 23:00:11 +02:00
}
2021-06-20 16:54:55 +02:00
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CopyStream ( StreamType & src_stream , StreamType & dst_stream )
2021-06-20 16:54:55 +02:00
{
2021-07-12 23:00:11 +02:00
if constexpr ( is_pikotools_stream )
{
2021-06-20 16:54:55 +02:00
dst_stream < < src_stream ;
2021-07-12 23:00:11 +02:00
}
else
{
2021-06-20 16:54:55 +02:00
dst_stream < < src_stream . str ( ) ;
2021-07-12 23:00:11 +02:00
}
2021-06-20 16:54:55 +02:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CopyStream ( pt : : WTextStream & src_stream , StreamType & dst_stream , bool should_escape )
2021-06-20 16:54:55 +02:00
{
2021-07-12 23:00:11 +02:00
if constexpr ( is_autoescape_stream )
2021-06-20 16:54:55 +02:00
{
2021-07-12 23:00:11 +02:00
dst_stream . Escape ( should_escape ) ;
dst_stream < < src_stream ;
2021-06-20 16:54:55 +02:00
}
else
{
2021-07-12 23:00:11 +02:00
if constexpr ( is_pikotools_stream )
2021-06-20 16:54:55 +02:00
{
2021-07-12 23:00:11 +02:00
dst_stream < < src_stream ;
}
else
{
if constexpr ( sizeof ( char ) = = sizeof ( typename StreamType : : char_type ) )
{
wide_stream_to_utf8 ( src_stream , dst_stream , false ) ;
}
else
{
dst_stream < < src_stream . to_str ( ) ;
}
2021-06-20 16:54:55 +02:00
}
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : RemoveStackFunData ( Stack & s )
2012-02-25 04:29:44 +01:00
{
2014-10-19 07:42:25 +02:00
if ( s . fun_data & & s . auto_remove )
2012-02-25 04:29:44 +01:00
{
2012-02-27 18:39:46 +01:00
delete s . fun_data ;
s . fun_data = 0 ;
2012-02-25 04:29:44 +01:00
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2011-04-26 19:17:06 +02:00
template < class CharType >
2021-07-12 23:00:11 +02:00
CharType Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ToLower ( CharType c )
2011-04-26 19:17:06 +02:00
{
if ( c > = ' A ' & & c < = ' Z ' )
return c - ' A ' + ' a ' ;
return c ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ConvertToBool ( const std : : wstring & str )
2015-03-08 03:31:21 +01:00
{
2021-05-23 10:02:51 +02:00
return ! str . empty ( ) ;
2015-03-08 03:31:21 +01:00
}
2014-10-17 23:36:55 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetMax ( size_t max_items_ , size_t max_for_items_ )
2010-11-22 02:23:32 +01:00
{
max_items = max_items_ ;
max_for_items = max_for_items_ ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : RecognizeSpecialChars ( bool spec )
2010-11-22 02:23:32 +01:00
{
special_chars = spec ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : TrimWhite ( bool trim )
2010-11-22 02:23:32 +01:00
{
trim_white = trim ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SkipNewLine ( bool skip )
2010-11-22 02:23:32 +01:00
{
skip_new_line = skip ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetMaxFilters ( size_t new_len )
2011-01-26 13:42:49 +01:00
{
// the table will be resized when Generate() method is called
filter_size = new_len ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SetStackSize ( size_t new_stack_size )
2012-02-27 18:39:46 +01:00
{
// the stack will be resized when Generate() method is called
stack_size = new_stack_size ;
}
2013-11-07 11:16:10 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Generate ( )
2010-11-22 02:23:32 +01:00
{
2011-04-26 19:17:06 +02:00
if ( is_generator_working )
2011-01-26 13:42:49 +01:00
{
2013-11-07 11:16:10 +01:00
CreateMsg ( L " generator busy " ) ;
2011-01-26 13:42:49 +01:00
return ;
}
2010-11-25 23:39:58 +01:00
break_generating = false ;
current_item = 0 ;
2012-02-27 18:39:46 +01:00
// in the case that there something has left on the stack
// from previous call to Generate()
// (an exception could have been thrown)
2014-10-17 23:36:55 +02:00
ClearForStack ( ) ;
2012-02-27 18:39:46 +01:00
2011-01-26 13:42:49 +01:00
ResizeFilterTab ( ) ;
2012-02-27 18:39:46 +01:00
ResizeStack ( ) ;
2014-10-17 23:36:55 +02:00
ResizeBlockStack ( ) ;
2021-05-28 16:10:16 +02:00
ResizeEzcFrameStack ( ) ;
2011-01-26 13:42:49 +01:00
filter_index = 0 ;
2012-02-27 18:39:46 +01:00
stack_index = 0 ;
2021-07-06 23:56:29 +02:00
ezc_frames_stack_index = 0 ;
2014-10-17 23:36:55 +02:00
block_stack_index = 0 ;
2010-11-25 23:39:58 +01:00
2014-10-17 23:36:55 +02:00
if ( ppattern )
2011-01-26 13:42:49 +01:00
{
try
{
2011-04-26 19:17:06 +02:00
is_generator_working = true ;
2014-10-17 23:36:55 +02:00
MakeText ( ppattern - > item_root ) ;
2015-11-12 10:53:20 +01:00
// !! IMPROVE ME we can print an error message if the stacks are not empty
// (some [end] statements has been omited)
2011-04-26 19:17:06 +02:00
is_generator_working = false ;
2011-01-26 13:42:49 +01:00
}
catch ( . . . )
{
2011-04-26 19:17:06 +02:00
is_generator_working = false ;
2011-01-26 13:42:49 +01:00
throw ;
}
}
2010-11-25 23:39:58 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Generate ( StreamType & out )
2010-11-25 23:39:58 +01:00
{
2015-11-12 10:53:20 +01:00
output_stream = & out ;
2021-07-12 23:00:11 +02:00
output_frames_streams = nullptr ;
2014-10-17 23:36:55 +02:00
Generate ( ) ;
2011-01-26 13:42:49 +01:00
}
2010-11-22 02:23:32 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Generate ( StreamType & out , OutStreams < StreamType , is_pikotools_stream > & out_streams )
2013-11-07 11:16:10 +01:00
{
2015-11-12 10:53:20 +01:00
output_stream = & out ;
2021-05-28 16:10:16 +02:00
output_frames_streams = & out_streams ;
2014-10-17 23:36:55 +02:00
Generate ( ) ;
2013-11-07 11:16:10 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Generate ( OutStreams < StreamType , is_pikotools_stream > & out_streams )
2013-11-07 11:16:10 +01:00
{
2021-07-12 23:00:11 +02:00
output_stream = nullptr ;
2021-05-28 16:10:16 +02:00
output_frames_streams = & out_streams ;
2014-10-17 23:36:55 +02:00
Generate ( ) ;
2013-11-07 11:16:10 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : IsTestingFunctionExistence ( )
2021-07-02 20:23:20 +02:00
{
return is_generating_if_def | | is_generating_if_not_def ;
}
2015-06-14 20:20:00 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-05 09:34:05 +01:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CheckBlockArgument ( int arg_index , FindHelperOld & find_helper )
2011-01-26 13:42:49 +01:00
{
2021-05-23 10:02:51 +02:00
if ( arg_index < 0 )
2015-06-14 20:20:00 +02:00
return false ;
// it's a numeric function -- an argument to a block e.g.: [1]
if ( block_stack_index > 0 )
2014-10-17 23:36:55 +02:00
{
2015-06-14 20:20:00 +02:00
BlockStack & block_stack = block_stack_tab [ block_stack_index - 1 ] ;
2013-11-07 11:16:10 +01:00
2021-05-23 10:02:51 +02:00
if ( size_t ( arg_index ) < block_stack . args . size ( ) )
2014-10-17 23:36:55 +02:00
{
2021-06-16 14:16:49 +02:00
find_helper . variable = & block_stack . args [ arg_index ] ;
2021-05-23 10:02:51 +02:00
return true ;
2014-10-17 23:36:55 +02:00
}
}
2013-11-07 11:16:10 +01:00
2021-05-23 10:02:51 +02:00
return false ;
2015-06-14 20:20:00 +02:00
}
2014-10-17 23:36:55 +02:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-05-31 18:37:09 +02:00
2021-11-05 09:34:05 +01:00
//template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
//bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::FindInModels(FindHelperOld & find_helper)
//{
// if( pmodels )
// {
// morm::Wrapper * m = pmodels->Find(*find_helper.fun_name);
//
// if( m )
// {
// find_helper.wrapper = m;
// return true;
// }
// }
//
// return false;
//}
2021-05-31 18:37:09 +02:00
2021-06-16 14:16:49 +02:00
# endif
2021-05-31 18:37:09 +02:00
2010-11-22 02:23:32 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:55:15 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrepareEnvStruct ( Env < StreamType > & info )
2010-11-22 02:23:32 +01:00
{
2021-08-29 20:55:15 +02:00
info . clear ( ) ;
2011-01-15 00:59:30 +01:00
2021-07-02 20:23:20 +02:00
info . is_for = is_generating_for ;
info . is_if = is_generating_if ;
info . is_if_def = is_generating_if_def ;
info . is_if_not_def = is_generating_if_not_def ;
info . is_normal = is_generating_normal ;
info . is_filter = is_generating_filter ;
info . iter = info . stack . iter ;
info . stack_tab = stack_tab . data ( ) ;
info . stack_index = stack_index - 1 ;
}
2012-02-24 13:04:36 +01:00
2011-04-26 19:17:06 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:55:15 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallFunction ( typename Functions < StreamType > : : UserFunction & function , Env < StreamType > & info )
2021-07-02 20:23:20 +02:00
{
PrepareEnvStruct ( info ) ;
( function ) ( info ) ;
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-05 09:34:05 +01:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallFunction (
typename Functions < StreamType > : : UserFunction & function , FindHelper & find_helper )
2010-11-22 02:23:32 +01:00
{
2021-07-02 20:23:20 +02:00
if ( ! IsTestingFunctionExistence ( ) )
2010-11-22 02:23:32 +01:00
{
2021-11-05 09:34:05 +01:00
// if( find_helper.parameters.empty() )
2021-07-02 20:23:20 +02:00
{
2021-11-06 19:07:39 +01:00
Env < StreamType > info ( * find_helper . result , find_helper . parameters , * find_helper . input , stack_tab [ stack_index - 1 ] , * stack_tab [ stack_index - 1 ] . item ) ;
2021-07-02 20:23:20 +02:00
CallFunction ( function , info ) ;
}
2021-11-05 09:34:05 +01:00
// else
// {
// Env<StreamType> info(result, parameters, in_stream, stack_tab[stack_index-1], *stack_tab[stack_index-1].item);
// CallFunction(function, info);
// }
2010-11-22 02:23:32 +01:00
}
2011-01-26 13:42:49 +01:00
}
2010-11-22 02:23:32 +01:00
2011-01-26 13:42:49 +01:00
2014-10-28 18:46:24 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : HasParam ( std : : vector < Var < StreamType > > & parameters , const wchar_t * param1 , const wchar_t * param2 )
2021-05-31 18:37:09 +02:00
{
2021-10-20 08:23:45 +02:00
for ( Var < StreamType > & var : parameters )
2021-05-31 18:37:09 +02:00
{
2021-08-29 20:35:15 +02:00
if ( var . is_equal ( param1 ) | | ( param2 & & var . is_equal ( param2 ) ) )
2021-05-31 18:37:09 +02:00
{
2021-08-29 20:35:15 +02:00
return true ;
2021-05-31 18:37:09 +02:00
}
}
2021-06-27 22:42:00 +02:00
return false ;
2021-05-31 18:37:09 +02:00
}
2021-06-27 22:42:00 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ShouldMakeSpaceDump ( std : : vector < Var < StreamType > > & parameters )
2021-06-22 18:01:47 +02:00
{
2021-06-27 22:42:00 +02:00
return HasParam ( parameters , L " dump " , L " dump_to_space " ) ;
}
2021-06-22 18:01:47 +02:00
2021-06-27 22:42:00 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : ShouldMakeJsonDump ( std : : vector < Var < StreamType > > & parameters )
2021-06-27 22:42:00 +02:00
{
return HasParam ( parameters , L " dump_to_json " ) ;
2021-06-22 18:01:47 +02:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : IsPrettyPrint ( std : : vector < Var < StreamType > > & parameters )
2021-06-27 22:42:00 +02:00
{
return HasParam ( parameters , L " pretty " ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-05 09:34:05 +01:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : DumpSpaceIfNeeded ( pt : : Space & space , FindHelper & find_helper )
2021-06-27 22:42:00 +02:00
{
2021-11-05 09:34:05 +01:00
bool dump_space = ShouldMakeSpaceDump ( find_helper . parameters ) ;
bool dump_json = ShouldMakeJsonDump ( find_helper . parameters ) ;
2021-06-27 22:42:00 +02:00
if ( dump_space | | dump_json )
2021-06-22 18:01:47 +02:00
{
2021-11-05 09:34:05 +01:00
bool pretty = IsPrettyPrint ( find_helper . parameters ) ;
2021-06-27 22:42:00 +02:00
if ( dump_space )
2021-06-22 18:01:47 +02:00
{
2021-11-06 19:07:39 +01:00
space . serialize_to_space_stream ( find_helper . result - > stream , pretty ) ;
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-06-27 22:42:00 +02:00
}
else
if ( dump_json )
{
2021-11-06 19:07:39 +01:00
space . serialize_to_json_stream ( find_helper . result - > stream , pretty ) ;
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-06-22 18:01:47 +02:00
}
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : DumpModelIfNeeded (
2021-10-20 08:23:45 +02:00
morm : : Model & model , Var < StreamType > & result , std : : vector < Var < StreamType > > & parameters )
2021-07-01 23:21:20 +02:00
{
bool dump_space = ShouldMakeSpaceDump ( parameters ) ;
bool dump_json = ShouldMakeJsonDump ( parameters ) ;
if ( dump_space | | dump_json )
{
//bool pretty = IsPrettyPrint(parameters);
if ( dump_space )
{
// not implemented yet
}
else
if ( dump_json )
{
// IMPLEMENT ME
// depends on the model_connector (flat connector)
// need to be made in a different way
pt : : TextStream temp_str ;
model . to_text ( temp_str , false , false ) ;
2021-08-29 20:35:15 +02:00
result . stream < < temp_str ; // what about escaping here? why Model::to_text() don't take WTextStream?
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-08-29 20:35:15 +02:00
//out_stream << temp_str;
2021-07-01 23:21:20 +02:00
}
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrintDate (
2021-11-05 09:34:05 +01:00
pt : : Date & date , FindHelper & find_helper )
2021-07-01 23:21:20 +02:00
{
2021-11-05 09:34:05 +01:00
bool is_roman = HasParam ( find_helper . parameters , L " roman " ) ;
bool is_no_sec = HasParam ( find_helper . parameters , L " no_sec " ) ;
bool only_date = HasParam ( find_helper . parameters , L " only_date " ) ;
bool only_time = HasParam ( find_helper . parameters , L " only_time " ) ;
2021-07-01 23:21:20 +02:00
2021-08-14 19:40:05 +02:00
if ( only_date )
{
2021-11-06 19:07:39 +01:00
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
date . SerializeYearMonthDay ( find_helper . result - > stream , is_roman ) ;
2021-08-14 19:40:05 +02:00
}
else
if ( only_time )
{
2021-11-06 19:07:39 +01:00
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-08-29 20:35:15 +02:00
2021-08-14 19:40:05 +02:00
if ( is_no_sec )
2021-11-06 19:07:39 +01:00
date . SerializeHourMin ( find_helper . result - > stream ) ;
2021-08-14 19:40:05 +02:00
else
2021-11-06 19:07:39 +01:00
date . SerializeHourMinSec ( find_helper . result - > stream ) ;
2021-08-14 19:40:05 +02:00
}
else
{
2021-11-06 19:07:39 +01:00
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
date . Serialize ( find_helper . result - > stream , is_roman , ! is_no_sec ) ;
2021-08-14 19:40:05 +02:00
}
2021-07-01 23:21:20 +02:00
}
2021-10-27 14:23:48 +02:00
/*
* these can be made as a simple function ( e . g . from winix )
* as a first argument let they take pt : : Date
*/
/*
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrintDatePart (
2021-10-27 14:23:48 +02:00
pt : : Date & date , const std : : wstring & field , std : : vector < Var < StreamType > > & parameters , Var < StreamType > & result )
2021-07-01 23:21:20 +02:00
{
2021-07-02 20:23:20 +02:00
bool is_test = IsTestingFunctionExistence ( ) ;
2021-07-01 23:21:20 +02:00
if ( field = = L " year " )
2021-07-02 20:23:20 +02:00
{
if ( ! is_test )
2021-08-29 20:35:15 +02:00
{
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-10-27 14:23:48 +02:00
result . stream < < date . year ;
2021-08-29 20:35:15 +02:00
}
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
else
if ( field = = L " month " )
2021-07-02 20:23:20 +02:00
{
if ( ! is_test )
2021-07-06 21:47:42 +02:00
{
bool is_roman = HasParam ( parameters , L " roman " ) ;
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-07-06 21:47:42 +02:00
if ( is_roman )
2021-10-27 14:23:48 +02:00
pt : : Date : : SerializeMonthAsRoman ( result . stream , date . month ) ;
2021-07-06 21:47:42 +02:00
else
2021-10-27 14:23:48 +02:00
result . stream < < date . month ;
2021-07-06 21:47:42 +02:00
}
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
else
if ( field = = L " day " )
2021-07-02 20:23:20 +02:00
{
if ( ! is_test )
2021-08-29 20:35:15 +02:00
{
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-10-27 14:23:48 +02:00
result . stream < < date . day ;
2021-08-29 20:35:15 +02:00
}
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
else
if ( field = = L " hour " )
2021-07-02 20:23:20 +02:00
{
if ( ! is_test )
2021-08-29 20:35:15 +02:00
{
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-10-27 14:23:48 +02:00
result . stream < < date . hour ;
2021-08-29 20:35:15 +02:00
}
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
else
if ( field = = L " min " )
2021-07-02 20:23:20 +02:00
{
if ( ! is_test )
2021-08-29 20:35:15 +02:00
{
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-10-27 14:23:48 +02:00
result . stream < < date . min ;
2021-08-29 20:35:15 +02:00
}
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
else
if ( field = = L " sec " )
2021-07-02 20:23:20 +02:00
{
if ( ! is_test )
2021-08-29 20:35:15 +02:00
{
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-10-27 14:23:48 +02:00
result . stream < < date . sec ;
2021-08-29 20:35:15 +02:00
}
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
else
2021-07-02 20:23:20 +02:00
{
2021-07-01 23:21:20 +02:00
return false ;
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
return true ;
}
2021-10-27 14:23:48 +02:00
*/
2021-07-01 23:21:20 +02:00
2021-06-25 16:16:30 +02:00
2021-10-27 14:23:48 +02:00
/*
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallDate (
2021-10-27 14:23:48 +02:00
pt : : Date & date , const std : : wstring & name , std : : vector < std : : wstring > & fields , size_t field_index , std : : vector < Var < StreamType > > & parameters , Var < StreamType > & result )
2021-07-02 20:23:20 +02:00
{
bool found = true ;
2021-10-27 14:23:48 +02:00
bool all_fields_known = ( field_index = = fields . size ( ) ) ;
2021-07-02 20:23:20 +02:00
if ( all_fields_known )
{
2021-10-27 14:23:48 +02:00
PrintDate ( date , parameters , result ) ;
2021-07-02 20:23:20 +02:00
}
else
{
2021-10-27 14:23:48 +02:00
found = PrintDatePart ( date , fields [ field_index ] , result , parameters ) ;
2021-07-02 20:23:20 +02:00
2021-10-27 14:23:48 +02:00
// if( found )
// field_index += 1;
2021-07-02 20:23:20 +02:00
2021-10-27 14:23:48 +02:00
// {
// if( !IsTestingFunctionExistence() )
// {
// CreateMsg(L"cannot find ", *find_helper.fun_name, fields, L", unknown property ", fields[find_helper.field_index].c_str(), L" of date object");
// }
//
// found = false;
// }
2021-07-02 20:23:20 +02:00
}
return found ;
}
2021-10-27 14:23:48 +02:00
*/
2021-07-02 20:23:20 +02:00
2021-11-21 21:08:06 +01:00
//template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
//void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CallSpaceObjectForLastField(pt::Space & space, FindHelper & find_helper)
//{
// if( !IsTestingFunctionExistence() )
// {
// // CHECKME should we convert the last value to last_res?
// DumpSpaceIfNeeded(space, find_helper);
// }
//}
2021-06-25 16:16:30 +02:00
2021-10-25 21:33:21 +02:00
//template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
//pt::Space * Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CallSpaceObjectForMiddleField(const std::wstring & root_space_name, std::vector<std::wstring> & fields, size_t field_index, pt::Space * space)
//{
// std::wstring & next_field = fields[field_index];
// space = space->get_space(next_field);
//
// if( !space && !IsTestingFunctionExistence() )
// {
// CreateMsg(L"cannot find space field: ", root_space_name, fields, field_index + 1);
// }
//
// return space;
//}
2021-06-25 16:16:30 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallSpaceTableForLastField (
2021-11-05 09:34:05 +01:00
morm : : SpaceWrapper & space_wrapper , pt : : Space & space , FindHelper & find_helper , size_t model_wrapper_space_table_index )
2021-06-25 16:16:30 +02:00
{
2021-11-05 09:34:05 +01:00
pt : : Space : : TableType * table = space . get_table ( ) ;
2021-06-25 16:16:30 +02:00
2021-07-02 20:23:20 +02:00
if ( is_generating_for )
2021-06-25 16:16:30 +02:00
{
// we are in [for...]statement, increment iterator and check the range
2021-07-01 23:21:20 +02:00
space_wrapper . increment_iterator ( model_wrapper_space_table_index , table - > size ( ) ) ;
2021-08-13 21:44:07 +02:00
space_wrapper . invalidate_iterators ( model_wrapper_space_table_index + 1 ) ;
2021-11-22 15:44:37 +01:00
size_t iterator_value = space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
2021-11-23 19:40:52 +01:00
bool loop_status = ( iterator_value < table - > size ( ) ) ;
//space_wrapper.set_last_for_loop_status(for_status);
find_helper . result - > set ( loop_status ) ;
}
else
{
find_helper . result - > set ( space , false ) ;
2021-06-25 16:16:30 +02:00
}
2021-11-22 15:44:37 +01:00
if ( ! IsTestingFunctionExistence ( ) & & find_helper . is_last_field ( ) )
2021-06-25 16:16:30 +02:00
{
2021-11-05 09:34:05 +01:00
DumpSpaceIfNeeded ( space , find_helper ) ;
2021-09-23 14:03:26 +02:00
2021-11-05 09:34:05 +01:00
if ( HasParam ( find_helper . parameters , L " index " ) )
2021-09-23 14:03:26 +02:00
{
2021-11-06 19:07:39 +01:00
find_helper . result - > stream < < space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-09-23 14:03:26 +02:00
}
2021-11-05 09:34:05 +01:00
if ( HasParam ( find_helper . parameters , L " index-one " ) )
2021-09-23 14:03:26 +02:00
{
2021-11-06 19:07:39 +01:00
find_helper . result - > stream < < ( space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) + 1 ) ;
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-09-23 14:03:26 +02:00
}
2021-06-25 16:16:30 +02:00
}
}
2021-07-02 20:23:20 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
pt : : Space * Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallSpaceTableForMiddleField (
2021-11-05 09:34:05 +01:00
morm : : SpaceWrapper & space_wrapper , pt : : Space & space_table , FindHelper & find_helper , size_t model_wrapper_space_table_index )
2021-06-25 16:16:30 +02:00
{
2021-11-05 09:34:05 +01:00
pt : : Space : : TableType * table = space_table . get_table ( ) ;
pt : : Space * space = nullptr ;
2021-06-25 16:16:30 +02:00
// check the current iterator, if it is correct then select the item from the table
2021-07-01 23:21:20 +02:00
size_t iterator_value = space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
2021-06-25 16:16:30 +02:00
if ( iterator_value < table - > size ( ) )
{
space = ( * table ) [ iterator_value ] ;
}
else
{
2021-07-02 20:23:20 +02:00
// this message can be print even for [if-def...]
2021-11-05 09:34:05 +01:00
//CreateMsg(L"space table: ", root_space_name, fields, field_index, L" is not initialized, have you forgotten to use [for...] statement?");
2021-06-25 16:16:30 +02:00
space = nullptr ;
}
return space ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrintLastSpaceField (
2021-11-05 09:34:05 +01:00
pt : : Space & space , FindHelper & find_helper )
2021-07-02 20:23:20 +02:00
{
2021-11-05 09:34:05 +01:00
bool no_escape = HasParam ( find_helper . parameters , L " raw " , L " noescape " ) ;
2021-07-02 20:23:20 +02:00
2021-08-29 20:35:15 +02:00
// FIXME what about escaping here?
2021-07-02 20:23:20 +02:00
if ( no_escape )
{
2021-08-29 20:35:15 +02:00
//pt::WTextStream str;
2021-11-06 19:07:39 +01:00
space . serialize_to_string ( find_helper . result - > stream ) ;
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-08-29 20:35:15 +02:00
//CopyStream(str, out_stream, false);
2021-07-02 20:23:20 +02:00
}
else
{
2021-08-29 20:35:15 +02:00
// space->serialize_to_string(out_stream);
2021-11-06 19:07:39 +01:00
space . serialize_to_string ( find_helper . result - > stream ) ;
find_helper . result - > type = Var < StreamType > : : TYPE_STREAM ;
2021-07-02 20:23:20 +02:00
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-24 13:19:27 +01:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallSpaceWrapper (
2021-11-05 09:34:05 +01:00
morm : : SpaceWrapper & space_wrapper , FindHelper & find_helper )
2021-06-22 18:01:47 +02:00
{
2021-11-05 09:34:05 +01:00
pt : : Space * space = space_wrapper . get_space ( ) ;
2021-09-23 04:11:20 +02:00
size_t model_wrapper_space_table_index = 0 ;
2021-06-22 18:01:47 +02:00
2021-11-24 13:19:27 +01:00
while ( find_helper . is_next_field ( ) )
2021-06-22 18:01:47 +02:00
{
if ( space - > is_object ( ) )
{
2021-11-24 13:19:27 +01:00
const std : : wstring & next_field = find_helper . next_field ( ) ;
2021-11-22 15:44:37 +01:00
pt : : Space * next_space = space - > get_space ( next_field ) ;
2021-10-25 21:33:21 +02:00
2021-11-22 15:44:37 +01:00
if ( next_space )
{
find_helper . field_index + = 1 ;
space = next_space ;
2021-11-21 21:08:06 +01:00
}
else
2021-06-22 18:01:47 +02:00
{
2021-11-23 19:40:52 +01:00
// may this is a global function so return true
return true ;
2021-06-22 18:01:47 +02:00
}
}
else
if ( space - > is_table ( ) )
{
2021-11-05 09:34:05 +01:00
if ( model_wrapper_space_table_index < space_wrapper . space_indices_table_size ( ) )
2021-06-22 18:01:47 +02:00
{
2021-11-24 13:19:27 +01:00
const std : : wstring & next_field = find_helper . next_field ( ) ;
2021-11-22 15:44:37 +01:00
2021-11-23 19:40:52 +01:00
if ( next_field = = L " first " )
2021-06-22 18:01:47 +02:00
{
2021-11-23 19:40:52 +01:00
find_helper . field_index + = 1 ;
2021-11-22 15:44:37 +01:00
2021-11-23 19:40:52 +01:00
if ( space - > table_size ( ) > 0 )
{
find_helper . result - > set ( * space - > value . value_table . front ( ) , false ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
return true ;
}
else
{
CreateMsg ( L " first is used but the table is empty " ) ; // IMPROVE the warning message
return false ;
}
}
else
if ( next_field = = L " last " )
2021-06-22 18:01:47 +02:00
{
2021-11-23 19:40:52 +01:00
find_helper . field_index + = 1 ;
2021-09-23 04:11:20 +02:00
2021-11-23 19:40:52 +01:00
if ( space - > table_size ( ) > 0 )
{
find_helper . result - > set ( * space - > value . value_table . back ( ) , false ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
return true ;
}
else
2021-09-23 04:11:20 +02:00
{
2021-11-23 19:40:52 +01:00
CreateMsg ( L " last is used but the table is empty " ) ; // IMPROVE the warning message
return false ;
2021-09-23 04:11:20 +02:00
}
2021-06-22 18:01:47 +02:00
}
2021-11-23 19:40:52 +01:00
pt : : Space * next_space = CallSpaceTableForMiddleField ( space_wrapper , * space , find_helper , model_wrapper_space_table_index ) ;
if ( ! next_space )
{
// a [for ...] was not used beforehand
2021-11-24 13:19:27 +01:00
// return true, this can be a global method such as 'size'
find_helper . result - > set ( * space , false ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-24 13:19:27 +01:00
return true ;
2021-11-23 19:40:52 +01:00
}
// put a constant somewhere
if ( next_field = = L " val " )
{
find_helper . field_index + = 1 ;
}
else
if ( next_field = = L " index " )
{
find_helper . field_index + = 1 ;
size_t iterator_value = space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
find_helper . result - > set ( static_cast < unsigned long long > ( iterator_value ) ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
return true ;
}
else
if ( next_field = = L " index-one " )
{
find_helper . field_index + = 1 ;
size_t iterator_value = space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
find_helper . result - > set ( static_cast < unsigned long long > ( iterator_value + 1 ) ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
return true ;
}
else
if ( next_field = = L " is_first " )
{
find_helper . field_index + = 1 ;
size_t iterator_value = space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
find_helper . result - > set ( iterator_value = = 0 ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
return true ;
}
else
if ( next_field = = L " is_last " )
{
find_helper . field_index + = 1 ;
size_t iterator_value = space_wrapper . get_space_iterator_value ( model_wrapper_space_table_index ) ;
find_helper . result - > set ( iterator_value + 1 = = space - > table_size ( ) ) ;
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
return true ;
}
else
{
space = next_space ;
break ;
}
space = next_space ;
2021-06-22 18:01:47 +02:00
}
else
{
2021-11-05 09:34:05 +01:00
CreateMsg ( L " " , find_helper . name , find_helper . fields , find_helper . field_index , L " exceeded the maximum number of fields for a space object " ) ;
2021-11-22 15:44:37 +01:00
return false ;
2021-06-22 18:01:47 +02:00
}
}
else
{
2021-10-25 21:33:21 +02:00
break ;
2021-06-22 18:01:47 +02:00
}
2021-09-23 04:11:20 +02:00
model_wrapper_space_table_index + = 1 ;
2021-06-22 18:01:47 +02:00
}
2021-07-02 20:23:20 +02:00
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-22 15:44:37 +01:00
if ( space - > is_table ( ) )
{
CallSpaceTableForLastField ( space_wrapper , * space , find_helper , model_wrapper_space_table_index ) ;
}
else
if ( ! IsTestingFunctionExistence ( ) )
2021-11-21 21:08:06 +01:00
{
2021-11-23 19:40:52 +01:00
//PrintLastSpaceField(*space, find_helper);
find_helper . result - > set ( * space , false ) ; // WARNING here a new space wrapper will be created, need to invastigate
2021-11-21 21:08:06 +01:00
2021-12-09 13:30:09 +01:00
if ( find_helper . is_last_field ( ) ) // find_index will be incremented and the result is always false here
2021-11-21 21:08:06 +01:00
DumpSpaceIfNeeded ( * space , find_helper ) ;
}
return true ;
2021-06-22 18:01:47 +02:00
}
2021-11-23 19:40:52 +01:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallSpace (
pt : : Space & root_space , FindHelper & find_helper )
{
pt : : Space * space = & root_space ;
while ( find_helper . field_index < find_helper . fields . size ( ) + 1 )
{
if ( space - > is_object ( ) )
{
2021-12-09 13:30:09 +01:00
const std : : wstring & current_field = find_helper . fields [ find_helper . field_index - 1 ] ;
pt : : Space * next_space = space - > get_space ( current_field ) ;
2021-11-23 19:40:52 +01:00
if ( next_space )
{
find_helper . field_index + = 1 ;
space = next_space ;
}
else
{
return true ;
}
}
else
if ( space - > is_table ( ) )
{
2021-11-24 13:19:27 +01:00
//CreateMsg(L"you cannot iterate through space table when the space is added without a wrapper"); // IMPROVE the message
//return false;
find_helper . result - > set ( * space , false ) ;
return true ;
2021-11-23 19:40:52 +01:00
}
else
{
break ;
}
}
2021-12-09 13:30:09 +01:00
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
if ( space - > is_table ( ) )
{
2021-11-24 13:19:27 +01:00
// CreateMsg(L"you cannot iterate through space table when the space is added without a wrapper"); // IMPROVE the message
// return false;
find_helper . result - > set ( * space , false ) ;
return true ;
2021-11-23 19:40:52 +01:00
}
else
if ( ! IsTestingFunctionExistence ( ) )
{
//PrintLastSpaceField(*space, find_helper);
find_helper . result - > set ( * space , false ) ;
2021-12-09 13:30:09 +01:00
if ( find_helper . is_last_field ( ) ) // !! find_index was incremented and here find_index is greater than fields.size(), this returns false
2021-11-23 19:40:52 +01:00
DumpSpaceIfNeeded ( * space , find_helper ) ;
}
return true ;
}
2021-05-31 18:37:09 +02:00
2021-06-16 14:16:49 +02:00
# ifdef EZC_HAS_MORM_LIBRARY
2021-05-31 18:37:09 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-17 17:33:51 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallModelField (
2021-11-05 09:34:05 +01:00
morm : : Model & model , FindHelper & find_helper )
2021-05-31 18:37:09 +02:00
{
2021-06-16 14:16:49 +02:00
/*
* if ' field ' is a POD type then ' str ' will be used in get_raw_value ( )
2021-06-20 16:54:55 +02:00
* if ' field ' is a getter method with pt : : Stream then ' str ' will be used too
2021-08-29 20:55:15 +02:00
* if ' field ' is a getter method which takes Env < > then out_stream will be used and ' str ' will be empty
2021-06-16 14:16:49 +02:00
*
*/
2021-10-27 14:23:48 +02:00
//pt::WTextStream str;
2021-06-19 20:18:30 +02:00
bool found = false ;
2021-05-31 18:37:09 +02:00
2021-11-06 19:07:39 +01:00
Env < StreamType > info ( * find_helper . result , find_helper . parameters , * find_helper . input , stack_tab [ stack_index - 1 ] , * stack_tab [ stack_index - 1 ] . item ) ;
2021-11-05 09:34:05 +01:00
found = model . get_raw_value ( nullptr , find_helper . current_name ( ) . c_str ( ) , nullptr , info ) ;
2021-05-31 18:37:09 +02:00
2021-10-27 14:23:48 +02:00
// if( found && !str.empty())
// {
// bool no_escape = HasParam(parameters, L"raw", L"noescape");
// CopyStream(str, result.stream, !no_escape);
// result.type = Var<StreamType>::TYPE_STREAM;
// }
2021-06-19 20:18:30 +02:00
return found ;
2021-06-16 14:16:49 +02:00
}
2021-10-27 14:23:48 +02:00
/*
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallModel (
2021-10-27 14:23:48 +02:00
morm : : Model & model , const std : : wstring & name , std : : vector < std : : wstring > & fields , size_t field_index ,
std : : vector < Var < StreamType > > & parameters , Var < StreamType > & result )
2021-06-16 14:16:49 +02:00
{
2021-07-02 20:23:20 +02:00
bool found = true ;
2021-07-01 23:21:20 +02:00
if ( find_helper . field_index = = fields . size ( ) )
{
// all fields items are models or models containers
2021-07-02 20:23:20 +02:00
if ( ! IsTestingFunctionExistence ( ) )
{
2021-08-29 20:35:15 +02:00
DumpModelIfNeeded ( model , result , parameters ) ;
2021-07-02 20:23:20 +02:00
}
2021-07-01 23:21:20 +02:00
}
else
if ( find_helper . field_index + 1 = = fields . size ( ) )
{
// last field is not a model nor a models container
2021-08-29 20:35:15 +02:00
if ( ! CallModelField ( model , fields [ find_helper . field_index ] , result , parameters , in_stream ) )
2021-07-01 23:21:20 +02:00
{
2021-07-02 20:23:20 +02:00
if ( ! IsTestingFunctionExistence ( ) )
{
CreateMsg ( L " cannot find " , * find_helper . fun_name , fields , L " , unknown property " , fields [ find_helper . field_index ] . c_str ( ) , L " of a model object " ) ;
}
found = false ;
2021-07-01 23:21:20 +02:00
}
}
else
{
2021-07-02 20:23:20 +02:00
if ( ! IsTestingFunctionExistence ( ) )
{
CreateMsg ( L " cannot find " , * find_helper . fun_name , fields , L " , " , fields [ find_helper . field_index ] . c_str ( ) , L " is not a model nor a model container nor a space " ) ;
}
found = false ;
2021-07-01 23:21:20 +02:00
}
2021-07-02 20:23:20 +02:00
return found ;
2021-07-01 23:21:20 +02:00
}
2021-10-27 14:23:48 +02:00
*/
2021-07-01 23:21:20 +02:00
2021-10-27 14:23:48 +02:00
/*
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : FindLastModelWrapper (
2021-10-27 14:23:48 +02:00
Var < StreamType > & var_parent , std : : vector < std : : wstring > & fields , size_t & field_index )
2021-07-01 23:21:20 +02:00
{
2021-10-27 14:23:48 +02:00
Var < StreamType > * var = & var_parent ;
for ( ; field_index < fields . size ( ) & & var - > has_model_object ( ) ; + + field_index )
2021-06-16 14:16:49 +02:00
{
2021-10-27 14:23:48 +02:00
std : : wstring & field = fields [ field_index ] ;
Var < StreamType > * child_var = var - > find_child ( field ) ;
2021-06-16 14:16:49 +02:00
2021-10-27 14:23:48 +02:00
if ( ! child_var )
2021-05-31 18:37:09 +02:00
{
2021-07-01 23:21:20 +02:00
morm : : Model * model = nullptr ;
2021-10-27 14:23:48 +02:00
if ( var - > model )
2021-07-01 23:21:20 +02:00
{
2021-10-27 14:23:48 +02:00
model = var - > model ;
2021-07-01 23:21:20 +02:00
}
else
2021-10-27 14:23:48 +02:00
if ( var - > model_container_wrapper )
2021-07-01 23:21:20 +02:00
{
2021-10-27 14:23:48 +02:00
model = var - > model_container_wrapper - > get_model ( ) ;
2021-07-01 23:21:20 +02:00
// this can return null for lists/vectors in a case when the iterator is not pointing to a valid item
}
2021-05-31 18:37:09 +02:00
2021-07-01 23:21:20 +02:00
if ( model )
2021-05-31 18:37:09 +02:00
{
2021-10-27 14:23:48 +02:00
// IMPROVE ME there'll be only one method to call a model
2021-07-01 23:21:20 +02:00
morm : : Wrapper new_wrapper = model - > get_wrapper ( nullptr , field . c_str ( ) ) ;
2021-05-31 18:37:09 +02:00
2021-07-01 23:21:20 +02:00
if ( new_wrapper . has_object ( ) )
2021-05-31 18:37:09 +02:00
{
2021-10-27 14:23:48 +02:00
Var < StreamType > child ;
if ( new_wrapper . model )
child . set ( * new_wrapper . model ) ;
if ( new_wrapper . model_container_wrapper )
child . set ( * new_wrapper . model_container_wrapper ) ;
if ( new_wrapper . date )
child . set ( * new_wrapper . date ) ;
if ( new_wrapper . space_wrapper )
child . set ( * new_wrapper . space_wrapper ) ;
child_var = var - > add_child ( field , new_wrapper ) ;
2021-05-31 18:37:09 +02:00
}
2021-10-27 14:23:48 +02:00
//////////////////////////////////////////////////////////////////////
2021-05-31 18:37:09 +02:00
}
2021-06-16 14:16:49 +02:00
}
2021-05-31 18:37:09 +02:00
2021-10-27 14:23:48 +02:00
if ( ! child_var )
2021-06-16 14:16:49 +02:00
break ;
2021-05-31 18:37:09 +02:00
2021-10-27 14:23:48 +02:00
var = child_var ;
2021-06-16 14:16:49 +02:00
}
}
2021-10-27 14:23:48 +02:00
*/
2021-06-16 14:16:49 +02:00
2021-10-27 14:23:48 +02:00
/*
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallWrapper (
2021-11-05 09:34:05 +01:00
FindHelperOld & find_helper , std : : vector < std : : wstring > & fields ,
2021-10-20 08:23:45 +02:00
Var < StreamType > & result , std : : vector < Var < StreamType > > & parameters , const StreamType & in_stream )
2021-06-16 14:16:49 +02:00
{
2021-07-02 20:23:20 +02:00
bool found = true ;
2021-08-29 20:35:15 +02:00
//last_res = false;
2021-07-01 23:21:20 +02:00
FindLastModelWrapper ( find_helper , fields ) ;
2021-06-16 14:16:49 +02:00
// if:
2021-07-01 23:21:20 +02:00
// helper.field_index == fields.size() - all fields items are either models, models containers, space or a date
// helper.field_index == fields.size()-1 - only the last field is not known
// helper.field_index < fields.size()-1 - there are more not known fields
2021-06-16 14:16:49 +02:00
2021-07-01 23:21:20 +02:00
bool all_fields_known = ( find_helper . field_index = = fields . size ( ) ) ;
bool last_field_not_known = ( find_helper . field_index + 1 = = fields . size ( ) ) ;
2021-06-22 18:01:47 +02:00
2021-10-25 21:33:21 +02:00
// if( find_helper.wrapper->space_wrapper )
// {
// found = CallSpace(find_helper, fields, result, parameters);
// }
2021-06-16 14:16:49 +02:00
2021-07-01 23:21:20 +02:00
if ( find_helper . wrapper - > date )
{
2021-08-29 20:35:15 +02:00
found = CallDate ( find_helper , fields , result , parameters ) ;
2021-06-16 14:16:49 +02:00
}
2021-07-01 23:21:20 +02:00
if ( find_helper . wrapper - > model )
2021-06-16 14:16:49 +02:00
{
2021-08-29 20:35:15 +02:00
found = CallModel ( * find_helper . wrapper - > model , find_helper , fields , result , parameters , in_stream ) ;
2021-07-01 23:21:20 +02:00
}
2021-06-23 06:53:43 +02:00
2021-07-01 23:21:20 +02:00
if ( find_helper . wrapper - > model_container_wrapper )
{
morm : : Model * model = find_helper . wrapper - > model_container_wrapper - > get_model ( ) ;
if ( model )
2021-06-16 14:16:49 +02:00
{
2021-08-29 20:35:15 +02:00
found = CallModel ( * model , find_helper , fields , result , parameters , in_stream ) ;
2021-06-16 14:16:49 +02:00
}
else
2021-07-01 23:21:20 +02:00
{
if ( last_field_not_known )
{
2021-07-02 20:23:20 +02:00
// can be printed even for [if-def...]
2021-07-01 23:21:20 +02:00
CreateMsg ( L " model " , * find_helper . fun_name , fields , L " is not initialized, have you forgotten to use [for ...] statement? " ) ;
2021-07-02 20:23:20 +02:00
found = false ;
2021-07-01 23:21:20 +02:00
}
}
if ( all_fields_known )
2021-06-16 14:16:49 +02:00
{
2021-07-02 20:23:20 +02:00
if ( is_generating_for )
2021-06-23 06:53:43 +02:00
{
2021-07-01 23:21:20 +02:00
find_helper . wrapper - > model_container_wrapper - > increment_iterator ( ) ;
find_helper . wrapper - > clear_childs ( ) ;
2021-08-29 20:35:15 +02:00
//last_res = find_helper.wrapper->model_container_wrapper->is_iterator_correct();
2021-06-23 06:53:43 +02:00
}
else
{
2021-07-02 20:23:20 +02:00
// for [if-def...] last_res will be set later
2021-08-29 20:35:15 +02:00
//last_res = !find_helper.wrapper->model_container_wrapper->is_container_empty();
2021-06-23 06:53:43 +02:00
}
2021-05-31 18:37:09 +02:00
}
}
2021-07-02 20:23:20 +02:00
return found ;
2021-05-31 18:37:09 +02:00
}
2021-10-27 14:23:48 +02:00
*/
2021-07-01 23:21:20 +02:00
2021-06-16 14:16:49 +02:00
# endif
2021-05-31 18:37:09 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallBlock ( Item & item_block ,
2021-10-20 08:23:45 +02:00
Var < StreamType > & result ,
std : : vector < Var < StreamType > > & parameters )
2014-10-17 23:36:55 +02:00
{
if ( block_stack_index > = block_stack_tab . size ( ) )
{
CreateMsg ( L " Generator exceeded allowed number of blocks " ) ;
return false ;
}
2021-07-02 20:23:20 +02:00
if ( ! IsTestingFunctionExistence ( ) )
{
StreamType * old_stream = output_stream ;
BlockStack & block_stack = block_stack_tab [ block_stack_index ] ;
2014-10-17 23:36:55 +02:00
2021-07-02 20:23:20 +02:00
block_stack . was_return = false ;
block_stack . args = parameters ;
2014-10-17 23:36:55 +02:00
2021-07-02 20:23:20 +02:00
output_stream = block_stack . out_stream ;
ClearStream ( * output_stream ) ;
block_stack_index + = 1 ;
2014-10-17 23:36:55 +02:00
2021-07-02 20:23:20 +02:00
MakeText ( item_block ) ;
2014-10-17 23:36:55 +02:00
2021-08-29 20:35:15 +02:00
CopyStream ( * output_stream , result . stream ) ;
2021-10-20 08:23:45 +02:00
result . type = Var < StreamType > : : TYPE_STREAM ;
2021-07-02 20:23:20 +02:00
// last_res is set by [return ...] statement or other last evaluated function
2014-10-17 23:36:55 +02:00
2021-08-29 20:35:15 +02:00
// FIXME what about result now?
2021-07-02 20:23:20 +02:00
ClearStream ( * output_stream ) ;
output_stream = old_stream ;
block_stack_index - = 1 ;
}
2014-10-17 23:36:55 +02:00
return true ;
}
2011-01-26 13:42:49 +01:00
2011-04-26 19:17:06 +02:00
2021-05-23 10:02:51 +02:00
2021-10-20 08:23:45 +02:00
2021-11-05 09:34:05 +01:00
//template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
//bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CallVariable(FindHelper & find_helper)
// //const std::wstring & name, std::vector<std::wstring> & fields, size_t & field_index, Var<StreamType> & result, std::vector<Var<StreamType>> & parameters)
//{
// Var<StreamType> * variable = FindVariable(find_helper);
// bool status = false;
//
// if( variable )
// {
// // here we cannot pass 'name' but the last field instead?
// status = EvaluateVariable(name, *variable, fields, field_index, parameters, result);
// }
//
// return status;
//}
2021-10-25 21:33:21 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
Var < StreamType > * Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : FindInScope ( const std : : wstring & name )
{
// here we should look in scopes (not implemented yet)
if ( pvars )
{
return pvars - > find ( name ) ;
}
return nullptr ;
}
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-05 09:34:05 +01:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : FindVariable ( FindHelper & find_helper )
2021-10-25 21:33:21 +02:00
{
2021-11-05 09:34:05 +01:00
find_helper . field_index = 0 ;
2021-11-08 00:41:36 +01:00
find_helper . previous_result = nullptr ;
find_helper . previous_var = nullptr ;
2021-11-05 09:34:05 +01:00
find_helper . previous_name = nullptr ;
2021-11-05 22:23:22 +01:00
find_helper . nested_calls = 0 ;
2021-10-25 21:33:21 +02:00
2021-11-06 19:07:39 +01:00
Var < StreamType > * origin_result = find_helper . result ;
2021-11-08 00:41:36 +01:00
std : : vector < Var < StreamType > > results ;
results . resize ( find_helper . fields . size ( ) + 1 ) ;
2021-11-06 19:07:39 +01:00
origin_result - > clear ( ) ;
2021-10-25 21:33:21 +02:00
do
{
2021-11-21 21:08:06 +01:00
find_helper . result = find_helper . is_last_field ( ) ? origin_result : & results [ find_helper . field_index ] ;
2021-11-06 19:07:39 +01:00
2021-11-05 09:34:05 +01:00
EvaluateVariable ( find_helper ) ;
2021-10-27 14:23:48 +02:00
2021-11-05 09:34:05 +01:00
if ( find_helper . found )
2021-10-27 14:23:48 +02:00
{
2021-11-24 13:19:27 +01:00
if ( find_helper . result - > type ! = Var < StreamType > : : TYPE_MODEL ) // TYPE_SPACE here too?
2021-11-06 19:07:39 +01:00
{
find_helper . input = find_helper . result ;
}
2021-11-23 19:40:52 +01:00
if ( find_helper . field_index = = 0 | | find_helper . field_index - 1 < find_helper . fields . size ( ) )
find_helper . previous_name = & find_helper . current_name ( ) ;
else
find_helper . previous_name = nullptr ;
2021-11-05 09:34:05 +01:00
find_helper . field_index + = 1 ;
2021-11-21 21:08:06 +01:00
// for space
if ( find_helper . field_index > = find_helper . fields . size ( ) + 1 & & find_helper . result ! = origin_result )
{
* origin_result = * find_helper . result ;
}
2021-10-25 21:33:21 +02:00
}
2021-10-27 14:23:48 +02:00
else
{
2021-12-09 13:30:09 +01:00
if ( find_helper . is_last_field ( ) ) // find_index was incremented and is greater than fields.size(), this returns false
2021-11-06 19:07:39 +01:00
{
find_helper . result - > clear ( ) ;
}
2021-10-27 14:23:48 +02:00
}
2021-11-06 19:07:39 +01:00
2021-10-25 21:33:21 +02:00
}
2021-11-05 09:34:05 +01:00
while ( find_helper . found & & find_helper . field_index < find_helper . fields . size ( ) + 1 ) ;
2021-10-25 21:33:21 +02:00
}
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-05 09:34:05 +01:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : EvaluateVariable ( FindHelper & find_helper )
2021-10-25 21:33:21 +02:00
{
2021-11-24 13:19:27 +01:00
bool was_child_found = false ;
2021-11-08 00:41:36 +01:00
find_helper . found = false ;
find_helper . current_var = nullptr ;
2021-11-05 09:34:05 +01:00
const std : : wstring & name = find_helper . current_name ( ) ;
2021-10-25 21:33:21 +02:00
2021-11-08 00:41:36 +01:00
if ( find_helper . previous_var )
{
2021-11-24 13:19:27 +01:00
find_helper . current_var = find_helper . previous_var - > find_child ( name ) ;
find_helper . found = was_child_found = ( find_helper . current_var ! = nullptr ) ;
2021-11-09 00:23:43 +01:00
if ( find_helper . current_var )
* find_helper . result = * find_helper . current_var ;
2021-11-23 19:40:52 +01:00
2021-11-08 00:41:36 +01:00
}
2021-11-21 21:08:06 +01:00
if ( ! find_helper . found & & find_helper . previous_name & & find_helper . previous_result )
2021-10-25 21:33:21 +02:00
{
2021-11-24 13:19:27 +01:00
if ( find_helper . previous_result - > type = = Var < StreamType > : : TYPE_MODEL )
2021-11-21 21:08:06 +01:00
{
2021-11-24 13:19:27 +01:00
// let functions return false to immediately return
// and find_helper can be either true or false
if ( ! EvaluateModel ( find_helper ) )
2021-11-23 19:40:52 +01:00
return ;
2021-11-24 13:19:27 +01:00
// what about if EvaluateModel returns another model or a space? we need a loop here?
2021-11-23 19:40:52 +01:00
}
else
if ( find_helper . previous_result - > type = = Var < StreamType > : : TYPE_SPACE )
{
if ( ! CallSpace ( * find_helper . previous_result - > space , find_helper ) )
return ;
2021-11-21 21:08:06 +01:00
}
2021-10-25 21:33:21 +02:00
}
2021-11-23 19:40:52 +01:00
// find_helper.field_index could have been changed by EvaluateModelField or CallSpace
2021-11-24 13:19:27 +01:00
if ( find_helper . field_index < find_helper . fields . size ( ) + 1 ) // add 'has_current_field()' to FindHelper
2021-10-27 14:23:48 +02:00
{
2021-11-23 19:40:52 +01:00
const std : : wstring & name = find_helper . current_name ( ) ;
2021-10-27 14:23:48 +02:00
2021-11-23 19:40:52 +01:00
if ( ! find_helper . found )
{
find_helper . result - > clear ( ) ; // is this clear here needed?
find_helper . current_var = FindInScope ( name ) ;
find_helper . found = ( find_helper . current_var ! = nullptr ) ;
if ( find_helper . current_var )
* find_helper . result = * find_helper . current_var ;
if ( find_helper . found )
{
if ( find_helper . current_var - > type = = Var < StreamType > : : TYPE_FUNCTION & & find_helper . current_var - > user_function )
{
EvaluateFunction ( find_helper . current_var - > user_function , find_helper ) ;
}
else
if ( find_helper . current_var - > type = = Var < StreamType > : : TYPE_DATE & & find_helper . current_var - > date )
{
// move me below (where TYPE_MODEL_CONTAINER_WRAPPER is used)
if ( find_helper . is_last_field ( ) )
PrintDate ( * find_helper . current_var - > date , find_helper ) ;
}
}
}
2021-11-20 22:02:18 +01:00
if ( find_helper . found )
2021-10-27 14:23:48 +02:00
{
2021-11-23 19:40:52 +01:00
if ( find_helper . result - > type = = Var < StreamType > : : Type : : TYPE_VOID & & ! find_helper . result - > stream . empty ( ) )
2021-11-05 09:34:05 +01:00
{
2021-11-23 19:40:52 +01:00
find_helper . result - > type = Var < StreamType > : : Type : : TYPE_STREAM ;
2021-11-05 09:34:05 +01:00
}
2021-11-23 19:40:52 +01:00
2021-11-24 13:19:27 +01:00
if ( find_helper . previous_var & & ! was_child_found )
2021-11-05 09:34:05 +01:00
{
2021-11-23 19:40:52 +01:00
// may only model_container_wrapper and space_wrapper here?
//find_helper.result->type == Var<StreamType>::TYPE_MODEL ||
if (
find_helper . result - > type = = Var < StreamType > : : TYPE_MODEL_CONTAINER_WRAPPER | |
find_helper . result - > type = = Var < StreamType > : : TYPE_SPACE_WRAPPER | |
find_helper . result - > type = = Var < StreamType > : : TYPE_FUNCTION )
{
2021-11-24 13:19:27 +01:00
find_helper . previous_var - > add_child ( name , * find_helper . result ) ;
// this result_child probably should be set as find_helper.current_var
2021-11-23 19:40:52 +01:00
}
2021-11-05 09:34:05 +01:00
}
2021-10-25 21:33:21 +02:00
2021-11-24 13:19:27 +01:00
if ( find_helper . result - > type = = Var < StreamType > : : TYPE_MODEL_CONTAINER_WRAPPER )
2021-11-09 00:23:43 +01:00
{
2021-11-24 13:19:27 +01:00
if ( ! EvaluateModelWrapper ( find_helper ) )
return ;
2021-11-09 00:23:43 +01:00
}
2021-11-24 13:19:27 +01:00
else
if ( find_helper . result - > type = = Var < StreamType > : : TYPE_SPACE_WRAPPER )
2021-11-08 00:41:36 +01:00
{
2021-11-24 13:19:27 +01:00
if ( ! CallSpaceWrapper ( * find_helper . result - > space_wrapper , find_helper ) )
return ;
2021-11-22 15:44:37 +01:00
}
2021-11-21 21:08:06 +01:00
2021-11-23 19:40:52 +01:00
find_helper . previous_var = find_helper . current_var ;
find_helper . previous_result = find_helper . result ;
}
else
2021-11-22 15:44:37 +01:00
{
2021-11-23 19:40:52 +01:00
find_helper . previous_var = nullptr ;
find_helper . previous_result = nullptr ;
2021-11-08 00:41:36 +01:00
}
2021-11-05 09:34:05 +01:00
}
2021-10-20 08:23:45 +02:00
}
2021-11-24 13:19:27 +01:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : EvaluateModel ( FindHelper & find_helper )
{
find_helper . found = CallModelField ( * find_helper . previous_result - > model , find_helper ) ;
if ( find_helper . found )
{
if ( find_helper . result - > type = = Var < StreamType > : : TYPE_FUNCTION & & find_helper . result - > user_function )
{
EvaluateFunction ( find_helper . result - > user_function , find_helper ) ;
if ( ! find_helper . found )
return false ; // maximum nested calls exceeded
}
}
return true ;
}
2021-11-05 22:23:22 +01:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-11-24 13:19:27 +01:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : EvaluateModelWrapper ( FindHelper & find_helper )
2021-11-05 22:23:22 +01:00
{
2021-11-24 13:19:27 +01:00
if ( find_helper . is_last_field ( ) )
2021-11-08 00:41:36 +01:00
{
2021-11-24 13:19:27 +01:00
if ( is_generating_for )
{
find_helper . result - > model_container_wrapper - > increment_iterator ( ) ;
bool loop_status = find_helper . result - > model_container_wrapper - > is_iterator_correct ( ) ;
find_helper . result - > set ( loop_status ) ; // may create a second bool status only for loops?
// find_helper.result was copied from currrent_var so it doesn't have childs here...(childs are not copied)
if ( find_helper . current_var )
find_helper . current_var - > clear_childs ( ) ;
// but it only clears child in the first level, is it correct?
// childs from different vars will not be cleared
}
2021-11-08 00:41:36 +01:00
}
else
2021-11-24 13:19:27 +01:00
if ( find_helper . is_next_field ( ) )
2021-11-05 22:23:22 +01:00
{
2021-11-24 13:19:27 +01:00
const std : : wstring & next_field = find_helper . next_field ( ) ;
2021-11-08 00:41:36 +01:00
2021-11-23 19:40:52 +01:00
// make a constant somewhere
2021-11-24 13:19:27 +01:00
if ( next_field = = L " val " )
2021-11-05 22:23:22 +01:00
{
2021-11-23 19:40:52 +01:00
find_helper . field_index + = 1 ;
2021-11-24 13:19:27 +01:00
morm : : Model * model = find_helper . result - > model_container_wrapper - > get_model ( ) ;
2021-11-23 19:40:52 +01:00
if ( model )
{
2021-11-24 13:19:27 +01:00
find_helper . result - > set ( * model ) ;
find_helper . found = true ;
2021-11-23 19:40:52 +01:00
}
else
{
// put some log (no [for] statement)
// CreateMsg(L"model ", name, fields, L" is not initialized, have you forgotten to use [for ...] statement?");
2021-11-24 13:19:27 +01:00
find_helper . result - > clear ( ) ;
2021-11-23 19:40:52 +01:00
find_helper . found = false ;
return false ;
}
2021-11-05 22:23:22 +01:00
}
}
2021-11-06 19:07:39 +01:00
return true ;
2021-11-05 22:23:22 +01:00
}
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : EvaluateFunction ( typename Var < StreamType > : : UserFunction user_function , FindHelper & find_helper )
{
bool call_again ;
do
{
call_again = false ;
CallFunction ( user_function , find_helper ) ;
find_helper . found = true ;
2021-11-06 19:07:39 +01:00
if ( find_helper . result - > type = = Var < StreamType > : : TYPE_FUNCTION & & find_helper . result - > user_function )
2021-11-05 22:23:22 +01:00
{
2021-11-06 19:07:39 +01:00
user_function = find_helper . result - > user_function ;
find_helper . result - > clear ( ) ;
2021-11-05 22:23:22 +01:00
find_helper . nested_calls + = 1 ;
if ( find_helper . nested_calls < = max_nested_calls )
{
call_again = true ;
}
else
{
CreateMsg ( L " Generator exceeded max nested calls " ) ;
find_helper . found = false ;
}
}
}
while ( call_again ) ;
}
2021-10-20 08:23:45 +02:00
/*
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CallVariable (
std : : vector < std : : wstring > & fields , size_t & field_index , Var < StreamType > & variable , Var < StreamType > & result , std : : vector < Var < StreamType > > & parameters , const StreamType & in_stream )
{
if ( variable . type = = Var < StreamType > : : TYPE_FUNCTION )
{
if ( variable . user_function )
{
CallFunction ( variable . user_function , result , parameters , in_stream ) ;
return true ;
}
else
{
// put some log that variable.user_function is null?
return false ;
}
}
else
if ( variable . type = = Var < StreamType > : : TYPE_MODEL )
{
if ( variable . model )
{
return XXXRenameMe ( variable , fields , field_index , result , parameters , in_stream ) ;
}
else
{
// put some log that model is null?
2021-08-29 20:35:15 +02:00
return false ;
}
2021-05-23 10:02:51 +02:00
}
else
{
2021-07-02 20:23:20 +02:00
if ( ! IsTestingFunctionExistence ( ) )
{
2021-08-29 20:35:15 +02:00
result = variable ;
//variable.serialize_to(out_stream);
//out_stream << variable.str;
//last_res = variable.res;
2021-07-02 20:23:20 +02:00
}
2021-05-23 10:02:51 +02:00
return true ;
}
}
2021-10-20 08:23:45 +02:00
*/
2021-05-23 10:02:51 +02:00
/*
* fun_name can be null , it is used only with [ let . . . ] statements
* and if not null then means : as a funcion name we are not using item_fun . name but fun_name
*
* return : true if a function , variable or block was found and called ( evaluated )
*/
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-08-29 20:35:15 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Call (
Item : : Function & item_fun ,
const std : : wstring * fun_name ,
2021-10-20 08:23:45 +02:00
Var < StreamType > & result ,
2021-11-06 19:20:11 +01:00
StreamType & in_stream )
2011-01-26 13:42:49 +01:00
{
2021-10-20 08:23:45 +02:00
std : : vector < Var < StreamType > > parameters ;
2014-10-17 23:36:55 +02:00
2021-08-29 20:35:15 +02:00
// FIXME where to set this?
// if constexpr(is_autoescape_stream)
// out_stream.Escape(true);
2021-07-12 23:00:11 +02:00
2022-04-12 19:10:10 +02:00
const std : : wstring * name = ( fun_name ) ? fun_name : & item_fun . name ;
2021-10-20 08:23:45 +02:00
Var < StreamType > * var = nullptr ;
2021-06-19 20:18:30 +02:00
2021-10-20 08:23:45 +02:00
if ( pvars )
{
var = pvars - > find ( * name ) ;
}
if ( ! var )
{
if ( ! IsTestingFunctionExistence ( ) )
CreateMsg ( name - > c_str ( ) , L " is not defined " ) ;
2021-05-31 18:37:09 +02:00
2021-06-16 14:16:49 +02:00
return false ;
2021-10-20 08:23:45 +02:00
}
2011-01-26 13:42:49 +01:00
2014-10-28 18:46:24 +01:00
parameters . resize ( item_fun . parameters . size ( ) ) ;
2014-10-17 23:36:55 +02:00
for ( size_t i = 0 ; i < item_fun . parameters . size ( ) ; + + i )
{
Item : : Function & fun_child = * item_fun . parameters [ i ] ;
2015-03-08 03:31:21 +01:00
if ( fun_child . is_function )
2014-10-17 23:36:55 +02:00
{
2021-11-06 19:20:11 +01:00
empty_stream . clear ( ) ;
2021-08-29 20:35:15 +02:00
Call ( fun_child , nullptr , parameters [ i ] , empty_stream ) ;
2014-10-17 23:36:55 +02:00
}
2014-10-28 18:46:24 +01:00
else
2014-10-17 23:36:55 +02:00
{
2021-10-20 08:23:45 +02:00
// currently in Patterns we can define only strings
2021-08-29 20:35:15 +02:00
parameters [ i ] . set ( fun_child . name ) ;
2014-10-17 23:36:55 +02:00
}
}
2021-11-06 19:07:39 +01:00
Var < StreamType > empty_input ; // fix me for filters
2021-11-06 19:20:11 +01:00
empty_input . type = Var < StreamType > : : TYPE_STREAM ;
empty_input . stream = in_stream ; // IMPROVEME don't copy here streams, let Var::stream be a pointer?
2021-11-06 19:07:39 +01:00
FindHelper find_helper ( * name , item_fun . fields , parameters ) ;
find_helper . result = & result ;
find_helper . input = & empty_input ;
2021-11-05 09:34:05 +01:00
FindVariable ( find_helper ) ;
return find_helper . found ;
2010-11-22 02:23:32 +01:00
}
2010-11-25 23:39:58 +01:00
2011-04-26 19:17:06 +02:00
// return: true if a function or variable was found and called
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : Call ( Item : : Function & item_fun , Var < StreamType > & result )
2011-01-15 00:59:30 +01:00
{
2021-08-29 20:35:15 +02:00
//return Call(item_fun, nullptr, stream_temp1, true, result, empty_stream);
2021-11-06 19:20:11 +01:00
empty_stream . clear ( ) ;
2021-08-29 20:35:15 +02:00
return Call ( item_fun , nullptr , result , empty_stream ) ;
2011-01-15 00:59:30 +01:00
}
2010-11-25 23:39:58 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
wchar_t Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CreateSpecialChar ( wchar_t c )
2010-11-22 02:23:32 +01:00
{
wchar_t res = 0 ;
if ( c = = ' r ' )
res = ' \r ' ;
else
if ( c = = ' n ' )
res = ' \n ' ;
else
if ( c = = ' t ' )
res = ' \t ' ;
else
if ( c = = ' s ' )
res = ' ' ;
else
if ( c = = ' \\ ' )
res = ' \\ ' ;
return res ;
}
2010-11-25 02:55:32 +01:00
// a special character is precedeed by a slash '\'
// if the special character is unknown the first slash is printing
// so "\t" gives one character of code 9
// and "\x" gives "\x"
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
const wchar_t * Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrintSpecialChar ( const wchar_t * start , const wchar_t * end )
2010-11-22 02:23:32 +01:00
{
2010-11-25 02:55:32 +01:00
wchar_t special = 0 ;
2010-11-22 02:23:32 +01:00
2010-11-25 02:55:32 +01:00
if ( * start = = ' \\ ' & & ( start + 1 ) ! = end )
special = CreateSpecialChar ( * ( start + 1 ) ) ;
if ( special )
{
output_stream - > write ( & special , 1 ) ;
start + = 2 ;
}
else
{
if ( ! skip_new_line | | * start ! = 10 )
output_stream - > write ( start , 1 ) ;
start + = 1 ;
}
return start ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrintSpecialText ( const wchar_t * start , const wchar_t * end )
2010-11-25 02:55:32 +01:00
{
2013-11-07 11:16:10 +01:00
if ( output_stream )
2010-11-22 02:23:32 +01:00
{
2013-11-07 11:16:10 +01:00
while ( start ! = end )
{
const wchar_t * end2 = start ;
2010-11-22 02:23:32 +01:00
2013-11-07 11:16:10 +01:00
// looking for a first new line character or a special char
// (for new line only if skip_new_line is true)
while ( end2 ! = end & & * end2 ! = ' \\ ' & & ( ! skip_new_line | | * end2 ! = 10 ) )
end2 + = 1 ;
2010-11-22 02:23:32 +01:00
2013-11-07 11:16:10 +01:00
// printing the first part of the text
if ( start ! = end2 )
output_stream - > write ( start , end2 - start ) ;
2010-11-22 02:23:32 +01:00
2013-11-07 11:16:10 +01:00
start = end2 ;
// skipping one or more new line characters or special chars
// (new lines only if skip_new_line is true)
while ( start ! = end & & ( * start = = ' \\ ' | | ( skip_new_line & & * start = = 10 ) ) )
start = PrintSpecialChar ( start , end ) ;
}
2010-11-22 02:23:32 +01:00
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : PrintNormalText ( const wchar_t * start , const wchar_t * end )
2010-11-22 02:23:32 +01:00
{
2013-11-07 11:16:10 +01:00
if ( output_stream )
2010-11-22 02:23:32 +01:00
{
2013-11-07 11:16:10 +01:00
if ( skip_new_line )
2010-11-22 02:23:32 +01:00
{
2013-11-07 11:16:10 +01:00
while ( start ! = end )
{
const wchar_t * end2 = start ;
2010-11-25 02:55:32 +01:00
2013-11-07 11:16:10 +01:00
// looking for a first new line character
while ( end2 ! = end & & * end2 ! = 10 )
end2 + = 1 ;
2010-11-25 02:55:32 +01:00
2013-11-07 11:16:10 +01:00
// printing the first part of the text (until the new line)
if ( start ! = end2 )
output_stream - > write ( start , end2 - start ) ;
2010-11-25 02:55:32 +01:00
2013-11-07 11:16:10 +01:00
start = end2 ;
// skipping one or more new line characters
while ( start ! = end & & * start = = 10 )
start + = 1 ;
}
}
else
{
if ( start ! = end )
output_stream - > write ( start , end - start ) ;
2010-11-22 02:23:32 +01:00
}
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : IsWhite ( wchar_t c )
2014-10-11 21:56:48 +02:00
{
// 13 (\r) is from a dos file at the end of a line (\r\n)
// 160 is a non-breaking space
if ( c = = ' ' | | c = = ' \t ' | | c = = 13 | | c = = 160 | | c = = 10 )
return true ;
return false ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : TrimWhite ( const wchar_t * & start , const wchar_t * & end )
2010-11-22 02:23:32 +01:00
{
2014-10-11 21:56:48 +02:00
while ( start ! = end & & IsWhite ( * start ) )
2010-11-22 02:23:32 +01:00
+ + start ;
2014-10-11 21:56:48 +02:00
while ( start ! = end & & IsWhite ( * ( end - 1 ) ) )
2010-11-22 02:23:32 +01:00
- - end ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : SkipWhite ( const wchar_t * & str )
2010-11-22 02:23:32 +01:00
{
2014-10-11 21:56:48 +02:00
while ( IsWhite ( * str ) )
2010-11-22 02:23:32 +01:00
str + = 1 ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
size_t Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : StrToSize ( const wchar_t * str , const wchar_t * * str_end )
2010-11-22 02:23:32 +01:00
{
2012-02-24 13:04:36 +01:00
size_t res = 0 ;
2010-11-22 02:23:32 +01:00
SkipWhite ( str ) ;
2012-02-24 13:04:36 +01:00
// !! IMPROVE ME
2010-11-22 02:23:32 +01:00
// overflow is not checked
while ( * str > = ' 0 ' & & * str < = ' 9 ' )
{
res * = 10 ;
res + = * str - ' 0 ' ;
str + = 1 ;
}
SkipWhite ( str ) ;
2013-11-07 11:16:10 +01:00
if ( str_end )
* str_end = str ;
2010-11-22 02:23:32 +01:00
return res ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CopyTmpStreamToOutputStreams ( Item : : Function & fun , StreamType & ezc_out_tmp_stream , StreamType & previous_stream )
2011-01-26 13:42:49 +01:00
{
2021-05-28 16:10:16 +02:00
if ( output_frames_streams )
2013-11-07 11:16:10 +01:00
{
2021-06-20 16:54:55 +02:00
CopyStream ( ezc_out_tmp_stream , previous_stream ) ;
2015-11-12 10:53:20 +01:00
2021-06-20 16:54:55 +02:00
for ( size_t s = 0 ; s < fun . parameters . size ( ) ; + + s )
2013-11-07 11:16:10 +01:00
{
2021-06-20 16:54:55 +02:00
std : : wstring & name = fun . parameters [ s ] - > name ;
auto imap = output_frames_streams - > streams_map . find ( name ) ;
2013-11-07 11:16:10 +01:00
2021-06-20 16:54:55 +02:00
if ( imap = = output_frames_streams - > streams_map . end ( ) )
2015-11-12 10:53:20 +01:00
{
2021-06-20 16:54:55 +02:00
if ( output_frames_streams - > streams_map . size ( ) < output_frames_streams - > streams_tab . size ( ) )
2015-11-12 10:53:20 +01:00
{
2021-06-20 16:54:55 +02:00
/* a new stream from the pool (output_stream_tab) is taken */
StreamType * stream = output_frames_streams - > streams_tab [ output_frames_streams - > streams_map . size ( ) ] ;
output_frames_streams - > streams_map . insert ( std : : make_pair ( name , stream ) ) ;
ClearStream ( * stream ) ;
CopyStream ( ezc_out_tmp_stream , * stream ) ;
2015-11-12 10:53:20 +01:00
}
else
{
2021-06-20 16:54:55 +02:00
CreateMsg ( L " limit of output streams in OutStreams<> has been reached " ) ;
2015-11-12 10:53:20 +01:00
}
}
2021-06-20 16:54:55 +02:00
else
{
StreamType * stream = imap - > second ;
CopyStream ( ezc_out_tmp_stream , * stream ) ;
}
2013-11-07 11:16:10 +01:00
}
}
2011-01-26 13:42:49 +01:00
}
2021-06-19 20:18:30 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CreateMsg ( const wchar_t * type , const wchar_t * arg )
2014-10-19 07:42:25 +02:00
{
2021-06-19 20:18:30 +02:00
if ( plog )
2014-10-19 07:42:25 +02:00
{
2021-06-20 16:54:55 +02:00
( * plog ) < < pt : : Log : : log2 < < " Ezc: " < < type ;
2014-10-19 07:42:25 +02:00
2021-06-19 20:18:30 +02:00
if ( arg )
{
2021-06-20 16:54:55 +02:00
( * plog ) < < ' ' < < arg ;
2021-06-19 20:18:30 +02:00
}
( * plog ) < < pt : : Log : : logend ;
}
2014-10-19 07:42:25 +02:00
}
2021-06-19 20:18:30 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CreateMsg ( const wchar_t * type , const std : : wstring & model_name , std : : vector < std : : wstring > & fields , size_t how_many_fields_print ,
2021-06-19 20:18:30 +02:00
const wchar_t * arg , const wchar_t * arg2 , const wchar_t * arg3 )
2015-11-12 10:53:20 +01:00
{
2021-06-19 20:18:30 +02:00
if ( plog )
{
( * plog ) < < pt : : Log : : log2 < < L " Ezc: " < < type < < model_name ;
2015-11-12 10:53:20 +01:00
2021-06-25 16:16:30 +02:00
for ( size_t i = 0 ; i < how_many_fields_print & & i < fields . size ( ) ; + + i )
2021-06-19 20:18:30 +02:00
{
2021-06-25 16:16:30 +02:00
( * plog ) < < ' . ' < < fields [ i ] ;
2021-06-19 20:18:30 +02:00
}
2010-11-22 02:23:32 +01:00
2021-06-19 20:18:30 +02:00
if ( arg )
{
( * plog ) < < arg ;
}
if ( arg2 )
{
( * plog ) < < arg2 ;
}
if ( arg3 )
{
( * plog ) < < arg3 ;
}
2010-11-22 02:23:32 +01:00
2021-06-19 20:18:30 +02:00
( * plog ) < < pt : : Log : : logend ;
}
}
2010-11-22 02:23:32 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CreateMsg ( const wchar_t * type , const std : : wstring & model_name , std : : vector < std : : wstring > & fields ,
2021-06-25 16:16:30 +02:00
const wchar_t * arg , const wchar_t * arg2 , const wchar_t * arg3 )
{
CreateMsg ( type , model_name , fields , fields . size ( ) , arg , arg2 , arg3 ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CreateMsg ( const std : : wstring & type , const std : : wstring & arg )
2010-11-22 02:23:32 +01:00
{
2010-11-25 23:39:58 +01:00
CreateMsg ( type . c_str ( ) , arg . c_str ( ) ) ;
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : CreateMsg ( const std : : wstring & type )
2010-11-22 02:23:32 +01:00
{
2010-11-25 23:39:58 +01:00
CreateMsg ( type . c_str ( ) ) ;
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : EvaluateProgramNode ( Item & item )
2018-10-30 00:50:10 +01:00
{
if ( output_stream )
{
if ( item . type = = Item : : item_function )
2018-10-30 21:59:17 +01:00
* output_stream < < " expression: " < < item . text ;
2018-10-30 00:50:10 +01:00
if ( item . type = = Item : : item_if )
2018-10-30 21:59:17 +01:00
* output_stream < < " if: " < < item . text ;
2018-10-30 00:50:10 +01:00
if ( item . type = = Item : : item_for )
2018-10-30 21:59:17 +01:00
* output_stream < < " for: " < < item . text ;
2018-10-30 00:50:10 +01:00
}
2021-08-29 20:35:15 +02:00
//last_res = false;
2018-10-30 00:50:10 +01:00
if ( expression_parser )
{
if ( expression_parser - > Parse ( item . text ) )
{
2021-08-29 20:35:15 +02:00
//last_res = expression_parser->LastResultToBool();
2018-10-30 21:59:17 +01:00
if ( output_stream )
{
* output_stream < < " -> " < < expression_parser - > LastResult ( ) ;
}
2018-10-30 00:50:10 +01:00
}
else
{
if ( output_stream )
{
2018-10-30 21:59:17 +01:00
* output_stream < < " -> syntax error when evaluating expression: error code: " < < ( int ) expression_parser - > LastError ( ) ;
2018-10-30 00:50:10 +01:00
}
}
}
2018-10-30 21:59:17 +01:00
if ( output_stream )
{
* output_stream < < " \n " ;
}
2018-10-30 00:50:10 +01:00
}
2010-11-22 02:23:32 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeItemText ( Item & item )
2010-11-22 02:23:32 +01:00
{
const wchar_t * start = item . text . c_str ( ) ;
const wchar_t * end = item . text . c_str ( ) + item . text . size ( ) ;
if ( trim_white )
TrimWhite ( start , end ) ;
if ( special_chars )
PrintSpecialText ( start , end ) ;
else
PrintNormalText ( start , end ) ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextContainer ( Item & item )
2010-11-22 02:23:32 +01:00
{
std : : vector < Item * > : : iterator i = item . item_tab . begin ( ) ;
for ( ; i ! = item . item_tab . end ( ) & & ! break_generating ; + + i )
2011-07-15 04:09:40 +02:00
MakeText ( * * i ) ;
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextFunction ( Item & item )
2010-11-22 02:23:32 +01:00
{
2012-02-24 13:04:36 +01:00
is_generating_normal = true ;
2013-11-07 11:16:10 +01:00
2018-10-30 00:50:10 +01:00
if ( program_mode )
2013-11-07 11:16:10 +01:00
{
2018-10-30 00:50:10 +01:00
EvaluateProgramNode ( item ) ;
2013-11-07 11:16:10 +01:00
}
else
{
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2021-11-06 19:20:11 +01:00
empty_stream . clear ( ) ;
2021-08-29 20:35:15 +02:00
2021-11-05 09:34:05 +01:00
if ( Call ( item . function , nullptr , result , empty_stream ) )
2021-08-29 20:35:15 +02:00
{
2021-11-05 09:34:05 +01:00
if ( output_stream )
{
2021-11-24 13:19:27 +01:00
if ( result . type = = Var < StreamType > : : TYPE_MODEL_CONTAINER_WRAPPER )
{
// IMPROVEME add model_container serialized as a table
// add a method 'serialize_to' to ModelContainerWrapper
}
else
if ( result . type = = Var < StreamType > : : TYPE_MODEL )
{
// IMPROVEME get rid of the tmp object
pt : : TextStream str_tmp ;
result . model - > to_text ( str_tmp ) ;
* output_stream < < str_tmp ; // what about escaping here?
}
else
{
result . serialize_to ( * output_stream ) ;
}
2021-11-05 09:34:05 +01:00
}
2021-08-29 20:35:15 +02:00
}
/*
2018-10-30 00:50:10 +01:00
if ( output_stream )
{
2021-08-29 20:35:15 +02:00
//Call(item.function, nullptr, *output_stream, false, result, empty_stream);
Call ( item . function , nullptr , result , empty_stream ) ;
result . serialize_to ( * output_stream ) ;
2018-10-30 00:50:10 +01:00
}
else
{
2021-08-29 20:35:15 +02:00
//Call(item.function, nullptr, stream_temp1, false, result, empty_stream);
Call ( item . function , nullptr , result , empty_stream ) ;
//ClearStream(stream_temp1);
2018-10-30 00:50:10 +01:00
}
2021-08-29 20:35:15 +02:00
*/
2013-11-07 11:16:10 +01:00
}
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextIf_go ( Item & item , bool result )
2010-11-22 02:23:32 +01:00
{
if ( result )
{
if ( item . item_tab . size ( ) > 0 )
MakeText ( * item . item_tab [ 0 ] ) ;
}
else
{
// second element can be (or not -- it's from [else])
if ( item . item_tab . size ( ) > 1 )
MakeText ( * item . item_tab [ 1 ] ) ;
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextIf ( Item & item )
2010-11-22 02:23:32 +01:00
{
2012-02-24 13:04:36 +01:00
is_generating_if = true ;
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2012-02-24 13:04:36 +01:00
2018-10-30 00:50:10 +01:00
if ( program_mode )
{
EvaluateProgramNode ( item ) ;
}
else
{
2021-08-29 20:35:15 +02:00
if ( ! Call ( item . function , result ) )
2018-10-30 00:50:10 +01:00
return ;
}
2010-11-22 02:23:32 +01:00
2021-08-29 20:35:15 +02:00
MakeTextIf_go ( item , result . to_bool ( ) ) ;
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextIfDef ( Item & item )
2021-07-02 20:23:20 +02:00
{
is_generating_if_def = true ;
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2021-07-02 20:23:20 +02:00
if ( program_mode )
{
//CHECKME
//EvaluateProgramNode(item);
}
else
{
2021-08-29 20:35:15 +02:00
Call ( item . function , result ) ;
2021-07-02 20:23:20 +02:00
}
2021-08-29 20:35:15 +02:00
MakeTextIf_go ( item , result . to_bool ( ) ) ;
2021-07-02 20:23:20 +02:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextIfNotDef ( Item & item )
2021-07-02 20:23:20 +02:00
{
is_generating_if_not_def = true ;
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2021-07-02 20:23:20 +02:00
if ( program_mode )
{
//CHECKME
//EvaluateProgramNode(item);
}
else
{
2021-08-29 20:35:15 +02:00
Call ( item . function , result ) ;
2021-07-02 20:23:20 +02:00
}
2021-08-29 20:35:15 +02:00
MakeTextIf_go ( item , ! result . to_bool ( ) ) ;
2021-07-02 20:23:20 +02:00
}
2010-11-22 02:23:32 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextFor ( Item & item )
2010-11-22 02:23:32 +01:00
{
2012-03-03 21:58:55 +01:00
stack_tab [ stack_index - 1 ] . is_for = true ;
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2012-03-03 21:58:55 +01:00
2012-02-27 18:39:46 +01:00
for ( ; ! break_generating ; stack_tab [ stack_index - 1 ] . iter + = 1 )
2010-11-22 02:23:32 +01:00
{
2012-02-27 18:39:46 +01:00
if ( stack_tab [ stack_index - 1 ] . iter > = max_for_items )
2010-11-22 02:23:32 +01:00
{
2015-03-08 03:31:21 +01:00
CreateMsg ( item . function . name . c_str ( ) ,
2010-11-22 02:23:32 +01:00
L " function exceeded a limit for a [for] statement " ) ;
break ;
}
2012-01-17 23:57:06 +01:00
// is_generating_for will be changed by next call to MakeText()
// so we should set it in each iterations
is_generating_for = true ;
2021-08-29 20:35:15 +02:00
result . clear ( ) ;
2018-10-30 00:50:10 +01:00
if ( program_mode )
{
EvaluateProgramNode ( item ) ;
}
else
{
2021-08-29 20:35:15 +02:00
//Call(item.function, nullptr, stream_temp1, true, result, empty_stream);
2021-11-06 19:20:11 +01:00
empty_stream . clear ( ) ;
2021-08-29 20:35:15 +02:00
Call ( item . function , nullptr , result , empty_stream ) ;
2018-10-30 00:50:10 +01:00
}
2010-11-22 02:23:32 +01:00
2021-11-23 19:40:52 +01:00
if ( ! result . to_bool ( ) )
2021-11-09 00:23:43 +01:00
break ;
2021-11-23 19:40:52 +01:00
// if( result.type == Var<StreamType>::Type::TYPE_MODEL_CONTAINER_WRAPPER )
// {
// if( !result.model_container_wrapper->is_iterator_correct() )
// break;
// }
// else
// if( result.type == Var<StreamType>::Type::TYPE_SPACE_WRAPPER )
// {
// if( !result.to_bool() )
// break;
// }
// else
// {
// break;
// }
2021-11-08 00:41:36 +01:00
2010-11-22 02:23:32 +01:00
if ( ! item . item_tab . empty ( ) )
2018-10-30 00:50:10 +01:00
MakeText ( * item . item_tab [ 0 ] ) ; // should be only one item
2010-11-22 02:23:32 +01:00
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextDefine ( Item & item , Var < StreamType > & var )
2010-11-22 02:23:32 +01:00
{
2021-08-29 20:35:15 +02:00
// var.str.clear();
// var.res = ConvertToBool(var.str);
// var.is_function = false;
var . clear ( ) ;
2021-05-23 10:02:51 +02:00
if ( item . function . parameters . empty ( ) )
2010-11-25 23:39:58 +01:00
{
return ;
}
2015-03-08 03:31:21 +01:00
2021-05-23 10:02:51 +02:00
if ( item . function . parameters . size ( ) > 1 )
2010-11-22 02:23:32 +01:00
{
2021-05-23 10:02:51 +02:00
CreateMsg ( L " [def] can have only one parameter " ) ;
return ;
}
Item : : Function & fun = * item . function . parameters [ 0 ] ;
if ( fun . is_function )
{
// call function
2021-08-29 20:35:15 +02:00
//if( Call(fun, nullptr, stream_temp_define, true, var, empty_stream) )
2021-11-06 19:20:11 +01:00
empty_stream . clear ( ) ;
2021-08-29 20:35:15 +02:00
if ( Call ( fun , nullptr , var , empty_stream ) )
2014-10-17 23:36:55 +02:00
{
2021-08-29 20:35:15 +02:00
//CopyStreamToString(stream_temp_define, var.str);
//var.res = last_res;
2014-10-17 23:36:55 +02:00
}
else
{
2021-05-23 10:02:51 +02:00
CreateMsg ( L " [def] unknown function/block/variable " , item . function . name ) ;
2014-10-17 23:36:55 +02:00
}
2010-11-22 02:23:32 +01:00
}
2021-05-23 10:02:51 +02:00
else
{
2021-08-29 20:35:15 +02:00
// var.str = fun.name;
// var.res = ConvertToBool(fun.name);
var . set ( fun . name ) ;
2021-05-23 10:02:51 +02:00
}
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextDefine ( Item & item )
2021-05-23 10:02:51 +02:00
{
2021-10-20 08:23:45 +02:00
return ;
/*
2021-05-23 10:02:51 +02:00
if ( ! can_use_vars | | ! pvars )
{
CreateMsg ( L " [def] statement not available " ) ;
return ;
}
2021-10-20 08:23:45 +02:00
Var < StreamType > & var = ( * pvars ) [ item . function . name ] ;
2021-05-23 10:02:51 +02:00
MakeTextDefine ( item , var ) ;
2021-10-20 08:23:45 +02:00
*/
2021-05-23 10:02:51 +02:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextDefineIfNotSet ( Item & item )
2021-05-23 10:02:51 +02:00
{
2021-10-20 08:23:45 +02:00
return ;
/*
2021-05-23 10:02:51 +02:00
if ( ! can_use_vars | | ! pvars )
{
CreateMsg ( L " [def?] statement not available " ) ;
return ;
}
Vars : : iterator vi = pvars - > find ( item . function . name ) ;
if ( vi = = pvars - > end ( ) )
{
2021-10-20 08:23:45 +02:00
Var < StreamType > & var = ( * pvars ) [ item . function . name ] ;
2021-05-23 10:02:51 +02:00
MakeTextDefine ( item , var ) ;
}
2021-10-20 08:23:45 +02:00
*/
2021-05-23 10:02:51 +02:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
2021-10-20 08:23:45 +02:00
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextLet ( Item & item , Var < StreamType > & var )
2021-05-23 10:02:51 +02:00
{
2021-08-29 20:35:15 +02:00
// var.str.clear();
// var.res = ConvertToBool(var.str);
// var.is_function = true;
2021-05-23 10:02:51 +02:00
if ( item . function . parameters . empty ( ) )
{
2021-08-29 20:35:15 +02:00
//var.is_function = false;
2021-05-23 10:02:51 +02:00
return ;
}
if ( item . function . parameters . size ( ) > 1 )
{
CreateMsg ( L " [let] can have only one parameter " ) ;
return ;
}
Item : : Function & fun = * item . function . parameters [ 0 ] ;
2021-08-29 20:35:15 +02:00
if ( fun . is_function )
var . set_function ( fun . name ) ;
else
var . set ( fun . name ) ;
// var.str = fun.name;
// var.is_function = fun.is_function;
// if( !fun.is_function )
// {
// var.res = ConvertToBool(var.str);
// }
2010-11-22 02:23:32 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextLet ( Item & item )
2021-05-23 10:02:51 +02:00
{
2021-10-20 08:23:45 +02:00
return ;
/*
2021-05-23 10:02:51 +02:00
if ( ! can_use_vars | | ! pvars )
{
CreateMsg ( L " [let] statement not available " ) ;
return ;
}
2021-10-20 08:23:45 +02:00
Var < StreamType > & var = ( * pvars ) [ item . function . name ] ;
2021-05-23 10:02:51 +02:00
MakeTextLet ( item , var ) ;
2021-10-20 08:23:45 +02:00
*/
2021-05-23 10:02:51 +02:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextLetIfNotSet ( Item & item )
2021-05-23 10:02:51 +02:00
{
2021-10-20 08:23:45 +02:00
return ;
/*
2021-05-23 10:02:51 +02:00
if ( ! can_use_vars | | ! pvars )
{
CreateMsg ( L " [let?] statement not available " ) ;
return ;
}
Vars : : iterator vi = pvars - > find ( item . function . name ) ;
if ( vi = = pvars - > end ( ) )
{
2021-10-20 08:23:45 +02:00
Var < StreamType > & var = ( * pvars ) [ item . function . name ] ;
2021-05-23 10:02:51 +02:00
MakeTextLet ( item , var ) ;
}
2021-10-20 08:23:45 +02:00
*/
2021-05-23 10:02:51 +02:00
}
2010-11-22 02:23:32 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextFilter ( Item & item )
2011-01-26 13:42:49 +01:00
{
if ( filter_index > = filter_tab . size ( ) )
{
CreateMsg ( L " Generator exceeded allowed number of filters " ) ;
return ;
}
2013-11-07 11:16:10 +01:00
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2011-01-26 13:42:49 +01:00
StreamType * old_stream = output_stream ;
output_stream = filter_tab [ filter_index ] ;
ClearStream ( * output_stream ) ;
filter_index + = 1 ;
if ( ! item . item_tab . empty ( ) )
MakeText ( * item . item_tab [ 0 ] ) ; // should be only one item - item_container
2012-02-24 13:04:36 +01:00
is_generating_filter = true ;
2011-01-26 13:42:49 +01:00
2013-11-07 11:16:10 +01:00
if ( old_stream )
{
2021-08-29 20:35:15 +02:00
//Call(item.function, nullptr, *old_stream, false, result, *output_stream);
Call ( item . function , nullptr , result , * output_stream ) ;
result . serialize_to ( * old_stream ) ;
2013-11-07 11:16:10 +01:00
}
else
{
2021-08-29 20:35:15 +02:00
// Call(item.function, nullptr, stream_temp1, true, result, *output_stream);
// ClearStream(stream_temp1);
Call ( item . function , nullptr , result , * output_stream ) ;
2013-11-07 11:16:10 +01:00
}
ClearStream ( * output_stream ) ;
2011-01-26 13:42:49 +01:00
output_stream = old_stream ;
filter_index - = 1 ;
}
2013-11-07 11:16:10 +01:00
2015-11-12 10:53:20 +01:00
/*
2021-05-28 16:10:16 +02:00
although we are using a stack for [ etc frame ] there is no need for the stack now
2015-11-12 10:53:20 +01:00
because the output is only a one - level map ( not nested structure )
2021-05-20 16:12:41 +02:00
but in the future we can use more complicated class like pt : : Space
2021-05-28 16:10:16 +02:00
and then nested [ ezc frame ] statements can product a better output
2015-11-12 10:53:20 +01:00
*/
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeEzcFrame ( Item & item )
2013-11-07 11:16:10 +01:00
{
2015-11-12 10:53:20 +01:00
std : : vector < std : : wstring * > output_stream_names ;
StreamType * old_stream ;
bool stream_added = true ;
2013-11-07 11:16:10 +01:00
2021-05-28 16:10:16 +02:00
if ( ezc_frames_stack_index > = ezc_frame_stack_tab . size ( ) )
2013-11-07 11:16:10 +01:00
{
2021-05-28 16:10:16 +02:00
CreateMsg ( L " Generator exceeded allowed number of [ezc frame] statements " ) ;
2015-11-12 10:53:20 +01:00
return ;
2013-11-07 11:16:10 +01:00
}
2015-11-12 10:53:20 +01:00
/*
2021-05-28 16:10:16 +02:00
if we encounter the first ezc frame statement without arguments e . g . [ ezc frame ] or just [ frame ]
2015-11-12 10:53:20 +01:00
then we can simply ignore it
*/
2021-05-28 16:10:16 +02:00
if ( item . function . parameters . empty ( ) & & ezc_frames_stack_index = = 0 )
2015-11-12 10:53:20 +01:00
stream_added = false ;
if ( stream_added )
2013-11-07 11:16:10 +01:00
{
2015-11-12 10:53:20 +01:00
old_stream = output_stream ;
2021-05-28 16:10:16 +02:00
output_stream = ezc_frame_stack_tab [ ezc_frames_stack_index ] ;
2015-11-12 10:53:20 +01:00
ClearStream ( * output_stream ) ;
2021-05-28 16:10:16 +02:00
ezc_frames_stack_index + = 1 ;
2013-11-07 11:16:10 +01:00
}
2015-11-12 10:53:20 +01:00
if ( ! item . item_tab . empty ( ) )
MakeText ( * item . item_tab [ 0 ] ) ; // should be only one item - item_container
if ( stream_added )
2013-11-07 11:16:10 +01:00
{
2015-11-12 10:53:20 +01:00
CopyTmpStreamToOutputStreams ( item . function , * output_stream , * old_stream ) ;
ClearStream ( * output_stream ) ;
output_stream = old_stream ;
2021-05-28 16:10:16 +02:00
ezc_frames_stack_index - = 1 ;
2013-11-07 11:16:10 +01:00
}
}
2015-11-12 10:53:20 +01:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextEzc ( Item & item )
2013-11-07 11:16:10 +01:00
{
2021-05-28 16:10:16 +02:00
if ( item . function . name = = L " frame " )
2021-06-29 23:38:38 +02:00
{
2021-05-28 16:10:16 +02:00
MakeEzcFrame ( item ) ;
2021-06-29 23:38:38 +02:00
}
else
if ( item . function . name = = L " clear_all_white_nodes " | | item . function . name = = L " trim_text_nodes " )
{
// text nodes are already cleared/trimmed by PatternParser
MakeTextContainer ( item ) ;
}
2013-11-07 11:16:10 +01:00
2015-03-08 03:31:21 +01:00
// in the future we can use more builtin functions
2013-11-07 11:16:10 +01:00
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeTextReturn ( Item & item )
2014-10-28 18:46:24 +01:00
{
2021-08-29 20:35:15 +02:00
//last_res = false;
2014-10-28 18:46:24 +01:00
if ( block_stack_index = = 0 )
{
// the [return] statement is not called from a [block]
CreateMsg ( L " [return] should be called from a [block] " ) ;
return ;
}
BlockStack & block_stack = block_stack_tab [ block_stack_index - 1 ] ;
block_stack . was_return = true ;
2015-03-08 03:31:21 +01:00
if ( item . has_function )
2014-10-28 18:46:24 +01:00
{
2021-10-20 08:23:45 +02:00
Var < StreamType > result ;
2021-08-29 20:35:15 +02:00
2015-03-08 03:31:21 +01:00
// output stream in [return] statement is ignored (we use only the stream produced by the whole block)
2014-10-28 18:46:24 +01:00
// this Call() sets last_res which is used later when we return to CallBlock()
2021-08-29 20:35:15 +02:00
//Call(item.function, nullptr, stream_temp1, false, result, empty_stream);
//ClearStream(stream_temp1);
2021-11-06 19:20:11 +01:00
empty_stream . clear ( ) ;
2021-08-29 20:35:15 +02:00
Call ( item . function , nullptr , result , empty_stream ) ;
2014-10-28 18:46:24 +01:00
}
}
2013-11-07 11:16:10 +01:00
2014-10-17 23:36:55 +02:00
2021-05-23 10:02:51 +02:00
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
bool Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : LimitAchieved ( )
2010-11-22 02:23:32 +01:00
{
if ( break_generating )
2012-02-27 18:39:46 +01:00
return true ;
2014-10-28 18:46:24 +01:00
if ( current_item > = max_items )
2010-11-22 02:23:32 +01:00
{
break_generating = true ;
2010-11-25 23:39:58 +01:00
CreateMsg ( L " Generator exceeded allowed number of elements " ) ;
2012-02-27 18:39:46 +01:00
return true ;
2010-11-22 02:23:32 +01:00
}
2014-10-28 18:46:24 +01:00
if ( stack_index > = stack_tab . size ( ) )
2012-02-27 18:39:46 +01:00
{
break_generating = true ;
CreateMsg ( L " Generator exceeded the stack size " ) ;
return true ;
}
2014-10-28 18:46:24 +01:00
if ( block_stack_index > 0 )
{
BlockStack & block_stack = block_stack_tab [ block_stack_index - 1 ] ;
if ( block_stack . was_return )
return true ;
}
2012-02-27 18:39:46 +01:00
return false ;
}
2021-07-12 23:00:11 +02:00
template < class StreamType , bool is_pikotools_stream , bool is_autoescape_stream >
void Generator < StreamType , is_pikotools_stream , is_autoescape_stream > : : MakeText ( Item & item )
2012-02-27 18:39:46 +01:00
{
if ( LimitAchieved ( ) )
return ;
2021-07-02 20:23:20 +02:00
current_item + = 1 ;
stack_index + = 1 ;
is_generating_for = false ;
is_generating_if = false ;
is_generating_if_def = false ;
is_generating_if_not_def = false ;
is_generating_normal = false ;
is_generating_filter = false ;
2012-01-17 23:57:06 +01:00
2012-02-27 18:39:46 +01:00
stack_tab [ stack_index - 1 ] . Clear ( ) ;
2016-04-04 17:53:11 +02:00
stack_tab [ stack_index - 1 ] . item = & item ;
2012-02-27 18:39:46 +01:00
2021-05-23 10:02:51 +02:00
if ( item . type = = Item : : item_text ) MakeItemText ( item ) ;
else if ( item . type = = Item : : item_container ) MakeTextContainer ( item ) ;
2021-06-20 16:54:55 +02:00
else if ( item . type = = Item : : item_function ) MakeTextFunction ( item ) ;
2021-05-23 10:02:51 +02:00
else if ( item . type = = Item : : item_if ) MakeTextIf ( item ) ;
2021-07-02 20:23:20 +02:00
else if ( item . type = = Item : : item_if_def ) MakeTextIfDef ( item ) ;
else if ( item . type = = Item : : item_if_not_def ) MakeTextIfNotDef ( item ) ;
2021-05-23 10:02:51 +02:00
else if ( item . type = = Item : : item_def ) MakeTextDefine ( item ) ;
else if ( item . type = = Item : : item_def_if_not_set ) MakeTextDefineIfNotSet ( item ) ;
else if ( item . type = = Item : : item_let ) MakeTextLet ( item ) ;
else if ( item . type = = Item : : item_let_if_not_set ) MakeTextLetIfNotSet ( item ) ;
else if ( item . type = = Item : : item_for ) MakeTextFor ( item ) ;
else if ( item . type = = Item : : item_filter ) MakeTextFilter ( item ) ;
else if ( item . type = = Item : : item_ezc ) MakeTextEzc ( item ) ;
else if ( item . type = = Item : : item_return ) MakeTextReturn ( item ) ;
2010-11-22 02:23:32 +01:00
else if ( item . type = = Item : : item_err )
2010-11-25 23:39:58 +01:00
CreateMsg ( L " a wrong directive " ) ;
2012-02-27 18:39:46 +01:00
RemoveStackFunData ( stack_tab [ stack_index - 1 ] ) ;
stack_index - = 1 ;
2010-11-22 02:23:32 +01:00
}
} // namespace Ezc
# endif
2014-11-02 18:26:56 +01:00