winix/winixd/templates/patterns.cpp

251 lines
5.2 KiB
C++

/*
* This file is a part of Winix
* and is distributed under the 2-Clause BSD licence.
* Author: Tomasz Sowa <t.sowa@ttmath.org>
*/
/*
* 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<HtmlTextStream> * obj)
{
ezc_obj = obj;
}
size_t Patterns::Add(const wchar_t * file_name, bool read_pattern)
{
for(size_t i=0 ; i<pat_tab.size() ; ++i)
{
if( pat_tab[i].references > 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 ; i<len ; ++i)
{
pattern_parser.ParseFile(templ.file_name, templ.patterns[i]);
locale_filter->Filter(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<pat_tab.size() ; ++i)
if( pat_tab[i].references > 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