/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2011-2015, 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: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. 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. * * 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 HOLDER 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. * */ #include "patterns.h" #include "core/log.h" namespace Winix { Patterns::Patterns() { del_white_items = false; ezc_fun = 0; ezc_blocks = 0; ezc_obj = 0; locale = 0; locale_filter = 0; } void Patterns::SetDeleteWhiteItems(bool del_white) { del_white_items = del_white; } void Patterns::SetDirectories(const std::wstring & tmpl_dir, const std::wstring & tmpl_dir_def) { templates_dir = tmpl_dir; templates_dir_def = tmpl_dir_def; } void Patterns::SetLocale(Locale * plocale) { locale = plocale; } void Patterns::SetLocaleFilter(LocaleFilter * plocale_filter) { locale_filter = plocale_filter; } void Patterns::SetEzcFunctions(TemplatesFunctions::EzcFun * fun) { ezc_fun = fun; } void Patterns::SetEzcBlocks(Ezc::Blocks * blocks) { ezc_blocks = blocks; } void Patterns::SetEzcObjects(Ezc::Objects * obj) { ezc_obj = obj; } size_t Patterns::Add(const wchar_t * file_name, bool read_pattern) { for(size_t i=0 ; i 0 && pat_tab[i].file_name == file_name ) { pat_tab[i].references += 1; return i; } } template_temp.to_delete = false; template_temp.file_name = file_name; template_temp.references = 1; template_temp.patterns.clear(); pat_tab.push_back(template_temp); if( read_pattern ) ReadPatterns(pat_tab.back()); return pat_tab.size()-1; } size_t Patterns::Add(const std::wstring & file_name, bool read_pattern) { return Add(file_name.c_str(), read_pattern); } void Patterns::ReadPatterns(Template & templ) { size_t len = locale->Size(); templ.patterns.resize(len); /* * pattern_parser.SetCommentary() is set beforehand */ pattern_parser.DeleteWhiteTextItems(del_white_items); pattern_parser.Directory(templates_dir, templates_dir_def); pattern_parser.SetLogger(&log); if( ezc_blocks ) pattern_parser.SetBlocks(*ezc_blocks); for(size_t i=0 ; iFilter(templ.patterns[i], *locale, i); } } // caching should be done after all patterns are read // because patterns can define blocks void Patterns::RebuildCache() { for(size_t a = 0 ; a < pat_tab.size() ; ++a) { for(size_t b = 0 ; b < pat_tab[a].patterns.size() ; ++b) { Ezc::Pattern & pat = pat_tab[a].patterns[b]; pat.ClearCache(); if( ezc_obj ) pat.CacheObjects(*ezc_obj); if( ezc_fun ) pat.CacheFunctions(*ezc_fun); if( ezc_blocks ) pat.CacheBlocks(*ezc_blocks); } } } Ezc::Pattern * Patterns::Get(size_t index, size_t lang_id) { if( index >= pat_tab.size() || pat_tab[index].references == 0 ) return 0; size_t lang_index = locale->IdToIndex(lang_id); if( lang_index >= pat_tab[index].patterns.size() ) return 0; return &pat_tab[index].patterns[lang_index]; } const std::wstring & Patterns::GetFileName(size_t index) { if( index >= pat_tab.size() || pat_tab[index].references == 0 ) return empty_str; return pat_tab[index].file_name; } void Patterns::Reload() { for(size_t i=0 ; i 0 ) ReadPatterns(pat_tab[i]); RebuildCache(); } void Patterns::Clear() { pat_tab.clear(); } void Patterns::Erase(size_t index) { if( index < pat_tab.size() && pat_tab[index].references > 0 ) { pat_tab[index].references -= 1; if( pat_tab[index].references == 0 ) { log << log3 << "Patterns: removing pattern: " << pat_tab[index].file_name << logend; pat_tab[index].file_name.clear(); pat_tab[index].patterns.clear(); // don't erase pat_tab.erase() here // because indices would be invalidated // those gaps will be cleared when Clear() method is called // normally in reload/templates winix function } } } size_t Patterns::Size() { return pat_tab.size(); } } // namespace Winix