/* * This file is a part of EZC -- Easy templating in C++ library * and is distributed under the BSD 3-Clause licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2007-2016, Tomasz Sowa * 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_funinfo #define headerfile_ezc_funinfo #include #include "item.h" namespace Ezc { /* a variable */ struct Var { std::wstring str; // a string value bool res; // a boolean value }; /* a base class for your own function data class */ struct FunData { FunData() { } virtual ~FunData() { } }; /* a generator's stack item each statement ([if ...] [for ...] [normal_funcion]) have its own stack item iter - is used only in [for...] - it is the current iteration (start from zero) for other statements it is always zero fun_data - by default this is null pointer, you can set it to a pointer to an object derived from FunData (this have sense only in [for...] statement because in other statements this object would be immediately removed) auto_remove - when true it means that object pointing by fun_data and for_name should be automatically removed -- (by using delete fun_data and delete for_name) is_for - true if the item is from [for] statement currently used only in [if-index] (it has to look for the last [for] item) */ struct Stack { size_t iter; FunData * fun_data; bool auto_remove; bool is_for; const Item * item; Stack() { Clear(); } ~Stack() { if( auto_remove ) { if( fun_data ) { delete fun_data; fun_data = 0; } } } void Clear() { iter = 0; fun_data = 0; auto_remove = true; is_for = false; item = 0; } }; // !! IMPROVE ME // the name is bad // may it should be called Env (environment) or FunEnv template struct FunInfo { // a result consists of a string and a boolean value // output stream StreamType & out; // return value from a user's function (default false if not set directly by the function) bool res; // table of parameters // the table can be empty std::vector & params; // the first parameter // you can always use it even if there are not any parameters (params is empty) // in such a way the reference points to an empty string const std::wstring & par; // an input stream used in [filter] statement // if there is other statement than [filter] then this is an empty stream const StreamType & in; // indicates that this function is from [for ...] statement bool is_for; // indicates that this function is from [if ...] statement // it is true for all kind of if's: if-one, if-any, if-no.... bool is_if; // indicates that this funcion is a normal statement e.g.: [funcion_name] bool is_normal; // indicates that this function is from a filter statement [filter ...] bool is_filter; // a pointer to the stack Stack * stack_tab; // current stack item size_t stack_index; // a stack's item from generator's stack // each function has a new stack item // on this stack you have iter (description below) and fun_data pointer // you can assign to it your own object derived from FunData // 'stack' is a reference to stack_tab[stack_index] Stack & stack; // the same as stack.iter (this is mainly for backward compatibility) // it indicates the number of a current iteration for the [for] statement (the first iteration is 0) // for other statements than [for] this is always zero size_t iter; // const Item & item; // arguments: output_stream, table_of_parameters, the_first_parameter FunInfo(StreamType & o, std::vector & pars, const std::wstring & first_par, const StreamType & input_stream, Stack & s, const Item & item_) : out(o), params(pars), par(first_par), in(input_stream), stack(s), item(item_) { Clear(); } void Clear() { res = false; // result is false by default is_for = false; is_if = false; is_normal = false; is_filter = false; iter = 0; stack_tab = 0; stack_index = 0; } /* * CHECK ME can it be done only for [for] statements? * * can return a null pointer if there is no such an item on the stack * * add a function with const wchar_t * */ Stack * FindLastFor(const std::wstring & name) { for(size_t i = stack_index ; i > 0 ; --i) { if( stack_tab[i-1].is_for && stack_tab[i-1].item->has_function ) { if( stack_tab[i-1].item->function.name == name ) { return &stack_tab[i-1]; } } } return 0; } Stack * FindLastFor(const std::wstring & name, const std::wstring & postfix) { for(size_t i = stack_index ; i > 0 ; --i) { if( stack_tab[i-1].is_for && stack_tab[i-1].item->has_function ) { if( stack_tab[i-1].item->function.name == name && stack_tab[i-1].item->function.postfix == postfix ) { return &stack_tab[i-1]; } } } return 0; } template FunUserObject * FindUserObject(const std::wstring & function_name, Stack ** ezc_stack = 0) { Stack * stack; if( item.has_function && item.function.is_function ) stack = FindLastFor(function_name, item.function.postfix); else stack = FindLastFor(function_name); if( ezc_stack ) *ezc_stack = stack; if( stack && stack->fun_data ) return dynamic_cast(stack->fun_data); return 0; } }; } // namespace Ezc #endif