├── tests ├── empty.txt ├── text.txt ├── incl.error.txt ├── override-empty.html ├── subdir │ ├── head.html │ ├── include_test_fail.html │ └── include_test_success.html ├── teng.no-print-escape.conf ├── dict.cs.txt ├── dict.en.txt ├── teng.debug.conf ├── override-one.html ├── base.html ├── override-two.html ├── override-super.html ├── teng.conf ├── base-nested-define.html ├── override-define.html ├── dict.txt ├── fuzz.cc └── utils.h ├── debian ├── compat ├── rules └── control ├── gdb-pretty-printers └── __init__.py ├── .gitignore ├── subprojects └── catch2-with-main.wrap ├── meson.options ├── README.md ├── fuzzer-coverage.sh ├── src ├── debug.h ├── aux.h ├── stringview.cc ├── hex.h ├── cache.cc ├── function.h ├── program.cc ├── semanticregex.h ├── fp.h ├── semantictern.h ├── aux.cc ├── semanticquery.h ├── parserfrag.cc ├── platform.h ├── jsonutils.h ├── util.h ├── position.cc ├── filestream.h ├── semantic.cc ├── semanticfrag.h ├── sourcelist.cc ├── semanticprint.h ├── utf8.h ├── semanticother.h ├── semantictern.cc ├── udf.cc ├── semantic.h ├── openframesapi.h ├── semanticexpr.h ├── semanticif.h ├── fragmentlist.cc ├── semanticblock.h ├── parserdiag.h ├── hex.cc ├── semanticregex.cc ├── sourcelist.h ├── logging.cc ├── logging.h ├── processor.h ├── semanticinheritance.h ├── filesystem.cc ├── yystype.cc ├── writer.cc ├── formatter.h ├── configuration.h ├── fragment.cc ├── functionutil.h ├── semanticquery.cc ├── function.cc ├── util.cc ├── functionother.h ├── semanticcase.cc ├── semanticother.cc ├── flexhelpers.h ├── instructionpointer.h └── dictionary.h ├── include └── teng │ ├── structs.h │ ├── types.h │ ├── config.h.in │ ├── udf.h │ ├── filesystem.h │ ├── stringify.h │ └── counted_ptr.h └── fuzzer-dict.txt /tests/empty.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 12 2 | -------------------------------------------------------------------------------- /gdb-pretty-printers/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/text.txt: -------------------------------------------------------------------------------- 1 | some text ${var} 2 | -------------------------------------------------------------------------------- /tests/incl.error.txt: -------------------------------------------------------------------------------- 1 | some 2 | ${missing} 3 | text 4 | -------------------------------------------------------------------------------- /tests/override-empty.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/subdir/head.html: -------------------------------------------------------------------------------- 1 | Head file 2 | -------------------------------------------------------------------------------- /tests/teng.no-print-escape.conf: -------------------------------------------------------------------------------- 1 | %enable shorttag 2 | %disable printescape 3 | -------------------------------------------------------------------------------- /tests/dict.cs.txt: -------------------------------------------------------------------------------- 1 | hello_world Ahoj svete! 2 | hello_europe Ahoj Evropo! 3 | dict_cs_txt value 4 | -------------------------------------------------------------------------------- /tests/dict.en.txt: -------------------------------------------------------------------------------- 1 | hello_world Hello world! 2 | hello_europe Hello Europe! 3 | dict_en_txt value 4 | -------------------------------------------------------------------------------- /tests/teng.debug.conf: -------------------------------------------------------------------------------- 1 | %enable shorttag 2 | %enable debug 3 | %enable bytecode 4 | %enable errorfragment 5 | -------------------------------------------------------------------------------- /tests/override-one.html: -------------------------------------------------------------------------------- 1 | head -------------------------------------------------------------------------------- /tests/subdir/include_test_fail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | compile_commands.json 3 | subprojects/*/ 4 | gdb-pretty-printers/__pycache__/ 5 | .cache/ 6 | -------------------------------------------------------------------------------- /tests/subdir/include_test_success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /subprojects/catch2-with-main.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | url = https://github.com/catchorg/Catch2.git 3 | revision = devel 4 | depth = 1 -------------------------------------------------------------------------------- /tests/base.html: -------------------------------------------------------------------------------- 1 | base -------------------------------------------------------------------------------- /tests/override-two.html: -------------------------------------------------------------------------------- 1 | headbody -------------------------------------------------------------------------------- /tests/override-super.html: -------------------------------------------------------------------------------- 1 | head---- -------------------------------------------------------------------------------- /tests/teng.conf: -------------------------------------------------------------------------------- 1 | %enable shorttag 2 | %maxdebugvallength 240 3 | %maxincludedepth 22 4 | 5 | ANY_PROPERTY "any value" 6 | 7 | -------------------------------------------------------------------------------- /tests/base-nested-define.html: -------------------------------------------------------------------------------- 1 | =TITLE= -------------------------------------------------------------------------------- /tests/override-define.html: -------------------------------------------------------------------------------- 1 | <?teng define block title?>unknown<?teng enddefine block?> -------------------------------------------------------------------------------- /meson.options: -------------------------------------------------------------------------------- 1 | option('docs', type : 'boolean', value : false, description : 'generate documentation') 2 | option('no-udf-locks', type : 'boolean', value : false, description : 'do not use locks for executing User Defined Functions') 3 | -------------------------------------------------------------------------------- /tests/dict.txt: -------------------------------------------------------------------------------- 1 | %expand yes 2 | 3 | hello_world hello world 4 | hello_europe hello europe 5 | dict_txt value 6 | html_value &some HTML text& 7 | html_small & 8 | version 1.1.1 9 | text_version version is #{version}! 10 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | export DH_VERBOSE=1 4 | 5 | %: 6 | dh $@ --buildsystem=meson --parallel 7 | 8 | override_dh_auto_configure: 9 | dh_auto_configure -- --buildtype=debugoptimized \ 10 | --wrap-mode=nofallback --force-fallback-for=catch2-with-main 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Teng is general purpose template engine for C++. 2 | 3 | It's not in active development, but it works and is used in production. 4 | 5 | # Doc 6 | 7 | Doc is available unfortunately only in intranet. 8 | 9 | # Versions 10 | 11 | * 5.x.x is the current version, 12 | * 4.x.x was temporary version, with regex fixes which change the binary compatibility, it's not maintained anymore, 13 | * 3.x.x can be found in libteng3 branch and only bug fixes are made, 14 | * 2.x.x can be found in libteng2 branch, it's not maintained anymore. 15 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: libteng 2 | Section: Seznam 3 | Priority: optional 4 | Maintainer: Seznam.cz a.s. 5 | Build-Depends: debhelper (>= 7.0.50), 6 | meson, 7 | cmake, 8 | bison, 9 | flex, 10 | libglib2.0-dev, 11 | pkg-config, 12 | libpcre2-8-0, 13 | libpcre2-dev, 14 | git 15 | Standards-Version: 3.7.2.2 16 | Vcs-Git: git://github.com/seznam/teng.git 17 | Vcs-Browser: https://github.com/seznam/teng 18 | 19 | Package: libteng-dev 20 | Architecture: any 21 | Section: Seznam 22 | Depends: libpcre2-dev, libglib2.0-dev 23 | Description: Development files for teng library 24 | Here are files necessary for developing new applications 25 | that use teng library and its C/C++ interface. 26 | -------------------------------------------------------------------------------- /fuzzer-coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ROOT="$1" 4 | shift 5 | 6 | BUILDIR="build/src" 7 | if [ ! -x "${ROOT}/${BUILDIR}/teng-fuzzer" ]; then 8 | BUILDIR="src" 9 | if [ ! -x "${ROOT}/${BUILDIR}/teng-fuzzer" ]; then 10 | BUILDIR="build/fuzz/src" 11 | if [ ! -x "${ROOT}/${BUILDIR}/teng-fuzzer" ]; then 12 | echo "no such executable: ${ROOT}/src/teng-fuzzer" 13 | exit 1 14 | else 15 | BIN="${ROOT}/${BUILDIR}/teng-fuzzer" 16 | PROF_RAW="${ROOT}/${BUILDIR}/teng-fuzzer.profraw" 17 | PROF_DATA="${ROOT}/${BUILDIR}/teng-fuzzer.profdata" 18 | fi 19 | else 20 | BIN="${ROOT}/${BUILDIR}/teng-fuzzer" 21 | PROF_RAW="${ROOT}/${BUILDIR}/teng-fuzzer.profraw" 22 | PROF_DATA="${ROOT}/${BUILDIR}/teng-fuzzer.profdata" 23 | fi 24 | else 25 | BIN="${ROOT}/${BUILDIR}/teng-fuzzer" 26 | PROF_RAW="${ROOT}/${BUILDIR}/teng-fuzzer.profraw" 27 | PROF_DATA="${ROOT}/${BUILDIR}/teng-fuzzer.profdata" 28 | fi 29 | 30 | OUT="${ROOT}/fuzzer-coverage-html" 31 | 32 | rm -f "${PROF_RAW}" "${PROF_DATA}" 33 | LLVM_PROFILE_FILE="${PROF_RAW}" "${BIN}" "$@" 34 | FUZZER_EXIT_CODE="$?" 35 | llvm-profdata merge -sparse "${PROF_RAW}" -o "${PROF_DATA}" 36 | llvm-cov show "${BIN}" -output-dir="${OUT}" -instr-profile="${PROF_DATA}" -format=html -Xdemangler c++filt -Xdemangler -n -ignore-filename-regex=".*glib-2.0.*" 37 | exit "${FUZZER_EXIT_CODE}" 38 | 39 | -------------------------------------------------------------------------------- /src/debug.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: $ 25 | * 26 | * DESCRIPTION 27 | * Teng debug macro. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-07-07 (burlog) 34 | * Created. 35 | */ 36 | 37 | #ifdef DEBUG 38 | #include 39 | #define DBG(...) do {if (!getenv("TENG_NO_DEBUG")) {__VA_ARGS__;}} while (0) 40 | #else /* DEBUG */ 41 | #define DBG(...) 42 | #endif /* DEBUG */ 43 | -------------------------------------------------------------------------------- /include/teng/structs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengstructs.h,v 1.6 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng data types. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-17 (vasek) 34 | * Created. 35 | */ 36 | 37 | #ifndef TENGSTRUCTS_H 38 | #define TENGSTRUCTS_H 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #endif /* TENGSTRUCTS_H */ 45 | 46 | -------------------------------------------------------------------------------- /include/teng/types.h: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengconfig.h.in,v 1.1 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng engine. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2007-05-21 (vasek) 34 | * Created. 35 | */ 36 | 37 | 38 | #ifndef TENGTYPES_H 39 | #define TENGTYPES_H 40 | 41 | #include 42 | 43 | namespace Teng { 44 | 45 | /** Integral type used inside teng 46 | */ 47 | typedef intmax_t IntType_t; 48 | 49 | } // namespace Teng 50 | 51 | #endif /* TENGTYPES_H */ 52 | -------------------------------------------------------------------------------- /src/aux.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tenginstruction.h,v 1.6 2010-06-11 07:46:26 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * gethostname() holder. 28 | * 29 | * AUTHORS 30 | * Martin Fousek 31 | * 32 | * HISTORY 33 | * 34 | */ 35 | 36 | #ifndef TENGAUX_H 37 | #define TENGAUX_H 38 | 39 | #include 40 | 41 | namespace Teng { 42 | 43 | /** Returns TLD domains derived from hostname or from enviroment TENG_TLD 44 | * varibale. The enviroment variable is preferred source of TLD domain. 45 | */ 46 | const std::string &get_tld(); 47 | 48 | } // namespace Teng 49 | 50 | #endif /* TENGAUX_H */ 51 | 52 | -------------------------------------------------------------------------------- /src/stringview.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id$ 25 | * 26 | * DESCRIPTION 27 | * String view and optionaly string holder. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 38 | 39 | #include "teng/stringview.h" 40 | 41 | namespace Teng { 42 | 43 | std::ostream &operator<<(std::ostream &os, const string_view_t &view) { 44 | os.write(view.data(), view.size()); 45 | return os; 46 | } 47 | 48 | std::ostream &operator<<(std::ostream &os, const mutable_string_view_t &view) { 49 | os.write(view.data(), view.size()); 50 | return os; 51 | } 52 | 53 | } // namespace Teng 54 | 55 | -------------------------------------------------------------------------------- /include/teng/config.h.in: -------------------------------------------------------------------------------- 1 | /* -*- C++ -*- 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengconfig.h.in,v 1.1 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng engine. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2007-05-21 (vasek) 34 | * Created. 35 | */ 36 | 37 | 38 | #ifndef TENGVERSION_H 39 | #define TENGVERSION_H 40 | 41 | #include 42 | 43 | namespace Teng { 44 | 45 | /** Teng library major version. 46 | */ 47 | #define TENG_MAJOR @TENG_MAJOR@ 48 | 49 | /** Teng library minor version. 50 | */ 51 | #define TENG_MINOR @TENG_MINOR@ 52 | 53 | /** Teng library version. 54 | */ 55 | #define TENG_VERSION "@TENG_MAJOR@.@TENG_MINOR@" 56 | 57 | } // namespace Teng 58 | 59 | #endif /* TENGVERSION_H */ 60 | 61 | -------------------------------------------------------------------------------- /src/hex.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tenghex.h,v 1.18 2008-11-20 23:32:29 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Hexadecimal encoding of bytes. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-14 (burlog) 34 | * Created. 35 | */ 36 | 37 | #ifndef TENGHEX_H 38 | #define TENGHEX_H 39 | 40 | #include 41 | 42 | namespace Teng { 43 | 44 | // conversion table of ascii hexadecimal ciphers to its numbers 45 | extern const uint8_t hex_values[256]; 46 | 47 | /** Decodes hex encoded byte. 48 | */ 49 | inline char unhex(uint8_t first, uint8_t second) { 50 | return uint8_t((hex_values[first] << 4) | hex_values[second]); 51 | } 52 | 53 | } // namespace Teng 54 | 55 | #endif /* TENGHEX_H */ 56 | 57 | -------------------------------------------------------------------------------- /src/cache.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengcache.cc,v 1.2 2005-06-22 07:16:07 romanmarek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng cache of files -- implementation. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-23 (vasek) 34 | * Created. 35 | * 2005-06-21 (roman) 36 | * Win32 support. 37 | */ 38 | 39 | 40 | #include 41 | #include 42 | 43 | #include "cache.h" 44 | #include "util.h" 45 | #include "platform.h" 46 | 47 | namespace Teng { 48 | 49 | std::string 50 | createCacheKeyForFilename(std::string filename) { 51 | return filename; 52 | } 53 | 54 | std::string 55 | createCacheKeyForString(const std::string &data) { 56 | return MD5Hexdigest(data); 57 | } 58 | 59 | } // namespace Teng 60 | -------------------------------------------------------------------------------- /src/function.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengfunction.h,v 1.2 2004-12-30 12:42:01 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng processor funcction (like len, round or formatDate) 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Vaclav Blazek 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2003-09-26 (jan) 36 | * Created. 37 | */ 38 | 39 | #ifndef TENGFUNCTION_H 40 | #define TENGFUNCTION_H 41 | 42 | #include "teng/invoke.h" 43 | 44 | namespace Teng { 45 | 46 | /** Teng builtin functions type. 47 | */ 48 | using Function_t 49 | = FunctionResult_t (*)(FunctionCtx_t &, const FunctionArgs_t &); 50 | 51 | /** 52 | * @short Finds builtin function in global list, returns pointer or nullptr. 53 | * 54 | * @param name name of the function 55 | */ 56 | Invoker_t findFunction(const std::string &name); 57 | 58 | } // namespace Teng 59 | 60 | #endif // TENGFUNCTION_H 61 | 62 | -------------------------------------------------------------------------------- /src/program.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengprogram.cc,v 1.2 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng program is sequence of teng instructions. 28 | * 29 | * AUTHORS 30 | * Stepan Skrob 31 | * Michal Bukovsky 41 | 42 | #include "filestream.h" 43 | #include "program.h" 44 | 45 | namespace Teng { 46 | 47 | void Program_t::dump(FILE *fp) const { 48 | FileStream_t stream(fp); 49 | dump(stream); 50 | } 51 | 52 | void Program_t::dump(std::ostream &out) const { 53 | for (auto &instr: instrs) { 54 | out << std::setw(3) << std::setfill('0') << std::noshowpos 55 | << std::distance(instrs.data(), &instr) << '\t'; 56 | instr.dump(out); 57 | out << std::endl; 58 | } 59 | } 60 | 61 | } // namespace Teng 62 | 63 | -------------------------------------------------------------------------------- /src/semanticregex.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICREGEX_H 40 | #define TENGSEMANTICREGEX_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | #include "teng/counted_ptr.h" 46 | 47 | namespace Teng { 48 | namespace Parser { 49 | 50 | /** Generates code implementing regex. 51 | */ 52 | counted_ptr generate_regex(Context_t *ctx, const Token_t ®ex); 53 | 54 | /** Generates code implementing regex matching. 55 | */ 56 | void generate_match(Context_t *ctx, const Token_t &token, const Token_t ®ex); 57 | 58 | } // namespace Parser 59 | } // namespace Teng 60 | 61 | #endif /* TENGSEMANTICREGEX_H */ 62 | 63 | -------------------------------------------------------------------------------- /src/fp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengprocessor.cc,v 1.15 2010-06-11 07:46:26 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng floating point utils. 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Vaclav Blazek 32 | * Michal Bukovsky 43 | 44 | namespace Teng { 45 | 46 | /** Does floating point calculation and checks fe exception flags. If 47 | * calculation violates any of them then function invokes error callback. 48 | */ 49 | template 50 | auto fp_safe(fp_calculation_t calculation, error_t error) { 51 | feclearexcept(FE_ALL_EXCEPT); 52 | auto result = calculation(); 53 | if (fetestexcept(FE_ALL_EXCEPT) & (~FE_INEXACT) & (~FE_INVALID)) 54 | return error(); 55 | return result; 56 | } 57 | 58 | } // namespace Teng 59 | 60 | #endif /* TENGFP_H */ 61 | 62 | -------------------------------------------------------------------------------- /src/semantictern.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICTERN_H 40 | #define TENGSEMANTICTERN_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Generates first conditional instruction for ternary operator. 50 | */ 51 | void generate_tern_op(Context_t *ctx, const Token_t &token); 52 | 53 | /** Finalizes jumps for true branch of ternary operator. 54 | */ 55 | void finalize_tern_op_true_branch(Context_t *ctx, const Token_t &token); 56 | 57 | /** Finalizes jumps for false branch of ternary operator. 58 | */ 59 | void finalize_tern_op_false_branch(Context_t *ctx); 60 | 61 | } // namespace Parser 62 | } // namespace Teng 63 | 64 | #endif /* TENGSEMANTICTERN_H */ 65 | 66 | -------------------------------------------------------------------------------- /src/aux.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tenginstruction.h,v 1.6 2010-06-11 07:46:26 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * gethostname() holder. 28 | * 29 | * AUTHORS 30 | * Martin Fousek 31 | * 32 | * HISTORY 33 | * 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | #include "aux.h" 40 | 41 | namespace Teng { 42 | namespace { 43 | 44 | std::string resolve_tld() { 45 | static const std::string default_tld = "__default__"; 46 | 47 | // take it from env 48 | if (char *teng_tld = getenv("TENG_TLD")) 49 | return teng_tld; 50 | 51 | // resolve local hostname 52 | char buf[1024] = {0}; 53 | if (gethostname(buf, sizeof(buf))) return default_tld; 54 | 55 | // take it from host domain 56 | std::string result = buf; 57 | size_t pos = result.rfind("."); 58 | if (pos == std::string::npos) return default_tld; 59 | return result.substr(pos + 1); 60 | } 61 | 62 | } // namespace 63 | 64 | const std::string &get_tld() { 65 | static const std::string value = resolve_tld(); 66 | return value; 67 | } 68 | 69 | } // namespace Teng 70 | 71 | -------------------------------------------------------------------------------- /src/semanticquery.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICQUERY_H 40 | #define TENGSEMANTICQUERY_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Generates runtime variable instruction from variable identifier for query 50 | * call. 51 | */ 52 | void generate_query(Context_t *ctx, const Variable_t &var, bool warn); 53 | 54 | /** Generates instructions implementing query expression. 55 | * If arity is not 1 then query is badly formated and instruction is not 56 | * generated. 57 | */ 58 | template 59 | NAryExpr_t query_expr(Context_t *ctx, const Token_t &token, uint32_t arity); 60 | 61 | } // namespace Parser 62 | } // namespace Teng 63 | 64 | #endif /* TENGSEMANTICQUERY_H */ 65 | 66 | -------------------------------------------------------------------------------- /src/parserfrag.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengparsercontext.cc,v 1.6 2006-06-21 14:13:59 sten__ Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng parser context -- implementation. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * Michal Bukovsky 32 | * 33 | * HISTORY 34 | * 2003-09-17 (vasek) 35 | * Created. 36 | * 2005-06-21 (roman) 37 | * Win32 support. 38 | * 2006-06-21 (sten__) 39 | * Commented out error reporting of exist function. 40 | * 2018-07-07 (burlog) 41 | * Extracted from tengparsercontext.cc. 42 | */ 43 | 44 | #include "logging.h" 45 | #include "program.h" 46 | #include "parserfrag.h" 47 | 48 | namespace Teng { 49 | namespace Parser { 50 | 51 | OpenFrames_t::~OpenFrames_t() { 52 | while (true) { 53 | while (!top().empty()) { 54 | auto frag = top().close_frag(); 55 | logWarning( 56 | program.getErrors(), 57 | program[frag.addr].pos(), 58 | "Unclosed directive" 59 | ); 60 | } 61 | if (size() == 1) return; 62 | close_frame(); 63 | } 64 | } 65 | 66 | } // namespace Parser 67 | } // namespace Teng 68 | 69 | -------------------------------------------------------------------------------- /src/platform.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengplatform.h,v 1.2 2006-01-29 10:56:16 franci_cz Exp $ 25 | * 26 | * DESCRIPTION 27 | * Define platform specific symbols. 28 | * 29 | * AUTHORS 30 | * Roman Marek 31 | * 32 | * HISTORY 33 | * 2005-06-11 (roman) 34 | * Created. 35 | */ 36 | 37 | #ifndef TENGPLATFORM_H 38 | #define TENGPLATFORM_H 39 | 40 | #ifdef WIN32 41 | 42 | #ifndef snprintf 43 | 44 | #ifndef _snprintf 45 | #include 46 | #endif //_snprintf 47 | 48 | #define snprintf _snprintf 49 | #endif //snprintf 50 | 51 | #endif //WIN32 52 | 53 | #ifndef WIN32 54 | #define ISROOT(path) ((path)[0] == '/') 55 | #else 56 | #define ISROOT(path) ((((path)[0] == '\\') && ((path)[1] == '\\')) || ((path)[1] == ':')) 57 | #endif //WIN32 58 | 59 | #ifdef WIN32 60 | #define CONVERTNAMEBYPLATFORM(path)\ 61 | string::size_type CNBP_slash = 0; \ 62 | string::size_type CNBP_nextslash = 0; \ 63 | static const basic_string ::size_type CNBP_npos = -1; \ 64 | while((CNBP_nextslash = (path).find('\\', CNBP_slash)) != CNBP_npos) { \ 65 | (path).replace(CNBP_nextslash, 1, string("/")); CNBP_slash = CNBP_nextslash; \ 66 | } 67 | #else 68 | #define CONVERTNAMEBYPLATFORM(path) 69 | #endif //WIN32 70 | 71 | #endif //TENGPLATFORM_H 72 | -------------------------------------------------------------------------------- /src/jsonutils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengstructs.cc,v 1.4 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng data types -- json utils. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-07-07 (burlog) 34 | * Created. 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "teng/stringview.h" 43 | 44 | namespace Teng { 45 | namespace json { 46 | 47 | inline void quoted_unicode_char(std::ostream &o, char ch) { 48 | o << "\\u00" << std::hex << std::setw(2) << std::setfill('0') << int(ch); 49 | } 50 | 51 | inline void quote_string(std::ostream &o, const string_view_t &value) { 52 | o << '"'; 53 | for (char ch: value) { 54 | switch (ch) { 55 | case 0 ... 8: 56 | case 11 ... 12: 57 | case 14 ... 31: quoted_unicode_char(o, ch); break; 58 | case '\n': o << "\\n"; break; 59 | case '\r': o << "\\r"; break; 60 | case '\t': o << "\\t"; break; 61 | case '\\': o << "\\\\"; break; 62 | case '"': o << "\\\""; break; 63 | case '/': o << "\\/"; break; 64 | default: o << ch; break; 65 | } 66 | } 67 | o << '"'; 68 | } 69 | 70 | } // namespace json 71 | } // namespace Teng 72 | 73 | -------------------------------------------------------------------------------- /include/teng/udf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * 25 | * DESCRIPTION 26 | * User defined functions. 27 | * 28 | * AUTHORS 29 | * Jan Nemec 30 | * Vaclav Blazek 31 | * Michal Bukovsky 32 | * 33 | * HISTORY 34 | * 2003-09-26 (jan) 35 | * Created. 36 | * 2018-06-07 (burlog) 37 | * Rewrite to C++. 38 | */ 39 | 40 | #ifndef TENGUDF_H 41 | #define TENGUDF_H 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | 49 | namespace Teng { 50 | namespace udf { 51 | 52 | // List of values are udf arguments. 53 | using Args_t = FunctionArgs_t; 54 | using Result_t = FunctionResult_t; 55 | 56 | // Type for user defined functions. 57 | using Function_t = std::function; 58 | 59 | /** 60 | * @short Registers user-defined function. 61 | * @param name name of the function (without udf.prefix) 62 | * @param udf user-defined callable object 63 | */ 64 | void registerFunction(const std::string &name, Function_t udf); 65 | 66 | /** 67 | * @short finds function in global UDF list, returns pointer or 0 68 | * @param name name of the function (with udf. prefix) 69 | */ 70 | Invoker_t findFunction(const std::string &name); 71 | 72 | } // namespace udf 73 | } // namespace Teng 74 | 75 | #endif /* TENGUDF_H */ 76 | 77 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengutil.h,v 1.3 2010-06-11 07:46:26 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng utilities. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-18 (vasek) 34 | * Created. 35 | */ 36 | 37 | 38 | #ifndef TENGUTIL_H 39 | #define TENGUTIL_H 40 | 41 | #include 42 | 43 | namespace Teng { 44 | 45 | /** @short Normalizes filename. 46 | * 47 | * Removes multiple '/', removes '.', resolves '..'. Path must be 48 | * absolute. 49 | * 50 | * @param filename normalized file (result) 51 | */ 52 | void normalizeFilename(std::string &filename); 53 | 54 | /** @short Compute MD5 hexdigest of data; 55 | * @param data input data 56 | * @return resulting hex digest 57 | */ 58 | std::string MD5Hexdigest(const std::string &data); 59 | 60 | /** @short Clip string to specified length and append "..." string 61 | * to end of clipped string (utf-8 safe) 62 | * @param str string to clip 63 | * @param len maximal length of str after clipping 64 | */ 65 | std::string clip(std::string str, unsigned int len); 66 | 67 | /** @short Converts ASCII string to lowercase ASCII string. 68 | */ 69 | std::string tolower(std::string str); 70 | 71 | /** Re-entrant version of strerror(3). 72 | */ 73 | std::string strerr(int errno_value); 74 | 75 | } // namespace Teng 76 | 77 | #endif // TENGUTIL_H 78 | 79 | -------------------------------------------------------------------------------- /src/position.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengerror.h,v 1.6 2011-01-19 06:39:45 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng error handling class. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * Michal Bukovsky 43 | #include 44 | 45 | #include "position.h" 46 | 47 | namespace Teng { 48 | 49 | std::string Pos_t::str() const { 50 | std::string result; 51 | result.append(*filename); 52 | if ((lineno > 0) && (colno >= 0)) { 53 | result.push_back(':'); 54 | result.append(std::to_string(lineno)); 55 | result.push_back(':'); 56 | result.append(std::to_string(colno)); 57 | } 58 | return result; 59 | } 60 | 61 | std::ostream &operator<<(std::ostream &o, const Pos_t &pos) { 62 | o << *pos.filename; 63 | if ((pos.lineno > 0) && (pos.colno >= 0)) 64 | o << ":" << pos.lineno << ":" << pos.colno; 65 | return o; 66 | } 67 | 68 | std::string Pos_t::basename() const { 69 | auto islash = std::find(filename->rbegin(), filename->rend(), '/'); 70 | return {islash.base(), filename->end()}; 71 | } 72 | 73 | } // namespace Teng 74 | 75 | -------------------------------------------------------------------------------- /src/filestream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengerror.h,v 1.6 2011-01-19 06:39:45 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * C++ stream writting to FILE *. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-14 (burlog) 34 | * First draft. 35 | * 36 | */ 37 | 38 | #ifndef TENGFILESTREAM_H 39 | #define TENGFILESTREAM_H 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | namespace Teng { 46 | 47 | /** Standard streambuf for FILE *. 48 | */ 49 | class FileBuf_t: public std::streambuf { 50 | public: 51 | FileBuf_t(FILE *file) 52 | : file(file) 53 | {} 54 | 55 | protected: 56 | /** Called when the one char should be writen. 57 | */ 58 | int_type overflow(int_type ch) override { 59 | return (ch == EOF) || (fwrite(&ch, 1, 1, file) != 1) 60 | ? EOF 61 | : ch; 62 | } 63 | 64 | /** Called when the char sequence should be writen. 65 | */ 66 | std::streamsize xsputn(const char *s, std::streamsize size) override { 67 | std::streamsize written = fwrite(s, 1, size, file); 68 | return (written != size) && ferror(file)? 0: written; 69 | } 70 | 71 | FILE *file; //!< the C stream 72 | }; 73 | 74 | /** C++ stream that writes to FILE *. 75 | */ 76 | class FileStream_t: public std::ostream { 77 | public: 78 | FileStream_t(FILE *file): fileBuf(file) {rdbuf(&fileBuf);} 79 | 80 | protected: 81 | FileBuf_t fileBuf; //!< the streambuf instance 82 | }; 83 | 84 | } // namespace Teng 85 | 86 | #endif // TENGFILESTREAM_H 87 | 88 | -------------------------------------------------------------------------------- /src/semantic.cc: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #include 40 | #include 41 | 42 | #include "lex2.h" 43 | #include "debug.h" 44 | #include "program.h" 45 | #include "instruction.h" 46 | #include "parsercontext.h" 47 | #include "semantic.h" 48 | 49 | namespace Teng { 50 | namespace Parser { 51 | namespace { 52 | 53 | } // namespace 54 | 55 | Token_t note_error(Context_t *ctx, const Token_t &token) { 56 | if (!ctx->error_occurred) { 57 | ctx->error_occurred = true; 58 | ctx->unexpected_token = token; 59 | ExprDiag_t::log_unexpected_token(ctx); 60 | } 61 | return token; 62 | } 63 | 64 | void reset_error(Context_t *ctx) { 65 | ctx->error_occurred = false; 66 | } 67 | 68 | void expr_diag(Context_t *ctx, diag_code_type new_diag_code, bool pop) { 69 | if (pop) ctx->expr_diag.pop(); 70 | ctx->expr_diag.push({new_diag_code, ctx->pos()}); 71 | } 72 | 73 | void expr_diag_sentinel(Context_t *ctx, diag_code new_diag_code) { 74 | ctx->expr_diag.push_sentinel(); 75 | expr_diag(ctx, new_diag_code, false); 76 | } 77 | 78 | void generate_val(Context_t *ctx, const Pos_t &pos, Value_t value) { 79 | generate(ctx, std::move(value), pos); 80 | } 81 | 82 | } // namespace Parser 83 | } // namespace Teng 84 | 85 | -------------------------------------------------------------------------------- /src/semanticfrag.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICFRAG_H 40 | #define TENGSEMANTICFRAG_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Generates as many as needed open frag instructions. 50 | */ 51 | void open_frag(Context_t *ctx, const Pos_t &pos, Variable_t &frag); 52 | 53 | /** Warns about invalid fragment name. 54 | */ 55 | void open_inv_frag(Context_t *ctx, const Pos_t &pos); 56 | 57 | /** Generates as many as needed close frag instructions. 58 | */ 59 | void close_frag(Context_t *ctx, const Pos_t &pos, bool invalid = false); 60 | 61 | /** Closes invalid fragment. 62 | */ 63 | void close_inv_frag(Context_t *ctx, const Pos_t &pos); 64 | 65 | /** Generates as many as needed close frag instructions. 66 | */ 67 | void 68 | close_unclosed_frag(Context_t *ctx, const Pos_t &pos, const Token_t &token); 69 | 70 | /** Generates code implementing debug fragment. 71 | */ 72 | void debug_frag(Context_t *ctx, const Pos_t &pos, bool warn = false); 73 | 74 | /** Generates code implementing bytecode fragment. 75 | */ 76 | void bytecode_frag(Context_t *ctx, const Pos_t &pos, bool warn = false); 77 | 78 | } // namespace Parser 79 | } // namespace Teng 80 | 81 | #endif /* TENGSEMANTICFRAG_H */ 82 | 83 | -------------------------------------------------------------------------------- /src/sourcelist.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengsourcelist.cc,v 1.3 2005-06-22 07:16:12 romanmarek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng list of sources -- implementation. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-23 (vasek) 34 | * Created. 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | 41 | #include "sourcelist.h" 42 | #include "logging.h" 43 | #include "util.h" 44 | 45 | namespace Teng { 46 | 47 | std::pair 48 | SourceList_t::push(const FilesystemInterface_t* filesystem, std::string filename) { 49 | // try to find existing entry 50 | for (std::size_t i = 0; i < sources.size(); ++i) 51 | if (sources[i]->filename == filename) 52 | return {&sources[i]->filename, i}; 53 | 54 | // stat file 55 | using ptr_t = std::unique_ptr; 56 | sources.emplace_back(ptr_t(new FileStat_t{filename, filesystem->hash(filename)})); 57 | return {&sources.back()->filename, sources.size() - 1}; 58 | } 59 | 60 | bool SourceList_t::isChanged(const FilesystemInterface_t* filesystem) const { 61 | for (auto &source: sources) try { 62 | auto new_hash = filesystem->hash(source->filename); 63 | if (new_hash != source->hash) return true; 64 | } catch (...) {/*ignore exceptions*/} 65 | return false; 66 | } 67 | 68 | const std::string *SourceList_t::operator[](std::size_t i) const { 69 | static const std::string empty; 70 | if (i < sources.size()) 71 | return &sources[i]->filename; 72 | return ∅ 73 | } 74 | 75 | } // namespace Teng 76 | 77 | -------------------------------------------------------------------------------- /src/semanticprint.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICPRINT_H 40 | #define TENGSEMANTICPRINT_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Generates print instruction. 50 | */ 51 | void generate_print(Context_t *ctx, bool print_escape = true); 52 | 53 | /** Generates lookup to dictionary instruction. 54 | */ 55 | void generate_dict_lookup(Context_t *ctx, const Token_t &token); 56 | 57 | /** Generates raw print instruction. 58 | */ 59 | void generate_raw_print(Context_t *ctx); 60 | 61 | /** Generates print instruction of given token value. 62 | */ 63 | void generate_raw_print(Context_t *ctx, const Token_t &token); 64 | 65 | /** Generates print instruction of given token value. It expects that value is 66 | * "undefined" which does not need escaping. 67 | */ 68 | void generate_inv_print(Context_t *ctx, const Token_t &inv); 69 | 70 | /** Generates lookup to dictionary instruction. 71 | */ 72 | void print_dict_lookup(Context_t *ctx, const Token_t &token); 73 | 74 | /** Generates undefined value due to invalid dict identifier. 75 | */ 76 | void print_dict_undef(Context_t *ctx, const Token_t &token); 77 | 78 | } // namespace Parser 79 | } // namespace Teng 80 | 81 | #endif /* TENGSEMANTICPRINT_H */ 82 | 83 | -------------------------------------------------------------------------------- /src/utf8.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengutf8.cc,v 1.18 2008-11-20 23:32:29 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Utf8 support in teng. 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-14 (burlog) 36 | * Moved from tengfunction.cc. 37 | */ 38 | 39 | #ifndef TENGUTF8_H 40 | #define TENGUTF8_H 41 | 42 | #include 43 | 44 | #include "teng/stringview.h" 45 | 46 | namespace Teng { 47 | namespace utf8 { 48 | 49 | /** Returns bytes length of the UTF-8 character. 50 | */ 51 | std::size_t charlen(char ch); 52 | 53 | /** Strlen for UTF-8 string. 54 | * @param str string 55 | * @return length of str 56 | */ 57 | std::size_t strlen(const string_view_t &str); 58 | 59 | /** Python-like substr for UTF-8 string. 60 | * @param str source string 61 | * @param s start index 62 | * @param e end index 63 | */ 64 | std::string 65 | substr( 66 | const string_view_t &str, 67 | int64_t s, 68 | int64_t e, 69 | std::string p1, 70 | std::string p2 71 | ); 72 | 73 | /** Find real indexes into string for UTF-8 substr. 74 | * @param str source string 75 | * @param s start index 76 | * @param e end index 77 | */ 78 | void substr(const string_view_t &str, int64_t &s, int64_t &e); 79 | 80 | /** Converts utf-8 string to lowercase.S 81 | */ 82 | std::string tolower(const string_view_t &str); 83 | 84 | /** Converts utf-8 string to uppercase. 85 | */ 86 | std::string toupper(const string_view_t &str); 87 | 88 | } // namespace utf8 89 | } // namespace Teng 90 | 91 | #endif /* TENGUTF8_H */ 92 | 93 | -------------------------------------------------------------------------------- /src/semanticother.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICOTHER_H 40 | #define TENGSEMANTICOTHER_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Opens given file and replace include directive with content of the file. 50 | */ 51 | void include_file(Context_t *ctx, const Pos_t &pos, const Options_t &opts); 52 | 53 | /** Writes warning into log error about ignored include. 54 | */ 55 | void ignore_include(Context_t *ctx, const Token_t &token, bool empty = false); 56 | 57 | /** Generates warning with unknown Teng directive message. 58 | */ 59 | void ignore_unknown_directive(Context_t *ctx, const Token_t &token); 60 | 61 | /** Generates warning about excessive options in directive that does not accept 62 | * any. 63 | */ 64 | void ignore_excessive_options(Context_t *ctx, const Pos_t &pos); 65 | 66 | /** Inserts new option to options list. It expects that ctx->opts_sym is valid 67 | * symbol (not moved out). 68 | */ 69 | void new_option(Context_t *ctx, const Token_t &name, Literal_t &&literal); 70 | 71 | /** Generates instructions implementing the function call. 72 | */ 73 | uint32_t generate_func(Context_t *ctx, const Token_t &name, uint32_t nargs); 74 | 75 | } // namespace Parser 76 | } // namespace Teng 77 | 78 | #endif /* TENGSEMANTICOTHER_H */ 79 | 80 | -------------------------------------------------------------------------------- /include/teng/filesystem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004-2018 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #ifndef TENGFILESYSTEM_H 21 | #define TENGFILESYSTEM_H 22 | 23 | #include 24 | #include 25 | 26 | namespace Teng { 27 | 28 | /** @short Abstract filesystem interface. 29 | */ 30 | class FilesystemInterface_t { 31 | public: 32 | virtual ~FilesystemInterface_t() = default; 33 | 34 | /** 35 | * @short Read contents from filesystem. 36 | * @param filename Name of the file in filesystem 37 | * @return Contents of the file in filesystem 38 | */ 39 | virtual std::string read(const std::string &filename) const = 0; 40 | 41 | /** 42 | * @short Make hash from file stats to allow caching as long as an file remains unchanged. 43 | * @param filename Name of the file in filesystem 44 | * @return Hash of the file stats 45 | */ 46 | virtual size_t hash(const std::string &filename) const = 0; 47 | }; 48 | 49 | /** @short Implementation of filesystem interface backed by real filesystem. 50 | */ 51 | class Filesystem_t : public FilesystemInterface_t { 52 | public: 53 | Filesystem_t(const std::string& root); 54 | virtual std::string read(const std::string &filename) const; 55 | virtual size_t hash(const std::string &filename) const; 56 | 57 | protected: 58 | std::string root; 59 | }; 60 | 61 | /** @short Implementation of filesystem interface backed by key-value storage. 62 | */ 63 | class InMemoryFilesystem_t : public FilesystemInterface_t { 64 | public: 65 | virtual std::string read(const std::string &filename) const 66 | { 67 | return storage.at(filename); 68 | } 69 | 70 | virtual size_t hash(const std::string &) const 71 | { 72 | return 0; // permanent cache 73 | } 74 | 75 | /** @short Key-value storage. 76 | */ 77 | std::map storage; 78 | }; 79 | 80 | } // namespace Teng 81 | 82 | #endif // TENGFILESYSTEM_H 83 | -------------------------------------------------------------------------------- /fuzzer-dict.txt: -------------------------------------------------------------------------------- 1 | "" 28 | "${" 29 | "}" 30 | "%{" 31 | "@{" 32 | "#{" 33 | "case" 34 | "_last" 35 | "_first" 36 | "_inner" 37 | "_index" 38 | "_count" 39 | "_error" 40 | "_parent" 41 | "_this" 42 | "udf" 43 | "count" 44 | "type" 45 | "exists" 46 | "repr" 47 | "defined" 48 | "isempty" 49 | "or" 50 | "and" 51 | "||" 52 | "&&" 53 | "!~" 54 | "=~" 55 | "eq" 56 | "ne" 57 | "ne" 58 | "gt" 59 | "lt" 60 | "le" 61 | "ge" 62 | "<=" 63 | ">=" 64 | "!=" 65 | "==" 66 | "++" 67 | "**" 68 | "/.*/" 69 | 70 | "file='base.html'" 71 | "space='nospace'" 72 | "space='onespace'" 73 | 74 | "a" 75 | "b" 76 | "c" 77 | "image" 78 | "profile" 79 | "subsections" 80 | "thread_count" 81 | "topNThreads" 82 | "current_section" 83 | "data" 84 | "icon_url" 85 | "answer_count" 86 | "1.1" 87 | "2.1" 88 | "1.1e-20" 89 | "1.1e20" 90 | "1" 91 | "2" 92 | "3" 93 | "4" 94 | "5" 95 | "6" 96 | "7" 97 | "8" 98 | "9" 99 | "10" 100 | "11" 101 | "12" 102 | "13" 103 | "14" 104 | "15" 105 | "16" 106 | "17" 107 | "18" 108 | "19" 109 | "20" 110 | "21" 111 | "22" 112 | "23" 113 | "24" 114 | "25" 115 | "26" 116 | "27" 117 | "28" 118 | "29" 119 | "30" 120 | "31" 121 | "\"str1\"" 122 | "\"str2\"" 123 | "\"str3\"" 124 | "\"str4\"" 125 | "\"str5\"" 126 | "\"str6\"" 127 | "\"str7\"" 128 | "\"str8\"" 129 | "\"str9\"" 130 | "\"str10\"" 131 | "\"str11\"" 132 | "\"str12\"" 133 | "\"str13\"" 134 | "\"str14\"" 135 | "\"str15\"" 136 | "\"str16\"" 137 | "\"str17\"" 138 | "\"str18\"" 139 | "\"str19\"" 140 | "\"str20\"" 141 | "\"str21\"" 142 | "\"str22\"" 143 | "\"str23\"" 144 | "\"str24\"" 145 | "\"str25\"" 146 | "\"str26\"" 147 | "\"str27\"" 148 | "\"str28\"" 149 | "\"str29\"" 150 | "\"str30\"" 151 | "\"str31\"" 152 | "\"a\"" 153 | "\"b\"" 154 | "\"c\"" 155 | "\"d\"" 156 | "\" \"" 157 | "\"Hello world! Hello world.\"" 158 | 159 | "int" 160 | "isnumber" 161 | "random" 162 | "round" 163 | "numformat" 164 | "len" 165 | "strtolower" 166 | "strtoupper" 167 | "substr" 168 | "wordsubstr" 169 | "reorder" 170 | "nl2br" 171 | "replace" 172 | "regex_replace" 173 | "escape" 174 | "unescape" 175 | "urlescape" 176 | "urlunescape" 177 | "quoteescape" 178 | "jsonify" 179 | "date" 180 | "now" 181 | "sectotime" 182 | "timestamp" 183 | "isenabled" 184 | "dictexist" 185 | "getdict" 186 | 187 | "/*" 188 | "*/" 189 | 190 | "[0]" 191 | "[1]" 192 | "[\"image\"]" 193 | "[\"answer_count\"]" 194 | "${a}" 195 | "${b}" 196 | "${c}" 197 | "a.b" 198 | 199 | "teng" 200 | "nl2b" 201 | 202 | -------------------------------------------------------------------------------- /include/teng/stringify.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengvalue.h,v 1.3 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng number to string. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-07 (burlog) 34 | * Created 35 | */ 36 | 37 | #ifndef TENGSTRINGIFY_H 38 | #define TENGSTRINGIFY_H 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include 45 | #include 46 | 47 | namespace Teng { 48 | 49 | /** Converts the integral number to string. 50 | */ 51 | template 52 | auto stringify(IntType_t value, writer_t &&writer, args_t &&...args) { 53 | // produce at least d 54 | char buffer[24]; 55 | auto len = snprintf(buffer, sizeof(buffer), "%jd", value); 56 | return writer(string_view_t(buffer, len), std::forward(args)...); 57 | } 58 | 59 | /** Converts the real number to string. 60 | */ 61 | template 62 | auto stringify(double value, writer_t &&writer, args_t &&...args) { 63 | // produce at least d.d 64 | char buffer[3 + DBL_MANT_DIG - DBL_MIN_EXP]; 65 | auto len = snprintf(buffer, sizeof(buffer), "%#f", value); 66 | 67 | // remove trailing zeroes 68 | for (; len > 2; --len) { 69 | if (buffer[len - 1] == '0') 70 | if (buffer[len - 2] != '.') 71 | continue; 72 | break; 73 | } 74 | 75 | // done 76 | return writer(string_view_t(buffer, len), std::forward(args)...); 77 | } 78 | 79 | /** Converts the number to string. 80 | */ 81 | template 82 | inline std::string stringify(type_t value) { 83 | return stringify(value, [] (const string_view_t &v) {return v.str();}); 84 | } 85 | 86 | } // namespace Teng 87 | 88 | #endif /* TENGSTRINGIFY_H */ 89 | 90 | -------------------------------------------------------------------------------- /src/semantictern.cc: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #include "debug.h" 40 | #include "program.h" 41 | #include "parserdiag.h" 42 | #include "instruction.h" 43 | #include "parsercontext.h" 44 | #include "semantictern.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | void generate_tern_op(Context_t *ctx, const Token_t &token) { 50 | ctx->curr_branch_addrs().push(ctx->program->size()); 51 | generate(ctx, token.pos); 52 | expr_diag(ctx, diag_code::tern_true_branch, false); 53 | } 54 | 55 | void finalize_tern_op_true_branch(Context_t *ctx, const Token_t &token) { 56 | // calculate jump from begin of tern op to false branch 57 | auto cond_addr = ctx->curr_branch_addrs().pop(); 58 | auto false_branch_offset = ctx->program->size() - cond_addr; 59 | 60 | // store address of jump from true branch 61 | ctx->curr_branch_addrs().push(ctx->program->size()); 62 | generate(ctx, token.pos); 63 | 64 | // fix conditional jump offset (relative addr) 65 | auto &instr = (*ctx->program)[cond_addr].as(); 66 | instr.addr_offset = false_branch_offset; 67 | 68 | // diagnostic code 69 | expr_diag(ctx, diag_code::tern_false_branch); 70 | } 71 | 72 | void finalize_tern_op_false_branch(Context_t *ctx) { 73 | auto true_branch_jump_addr = ctx->curr_branch_addrs().pop(); 74 | auto tern_op_end_offset = ctx->program->size() - true_branch_jump_addr - 1; 75 | auto &instr = (*ctx->program)[true_branch_jump_addr].as(); 76 | instr.addr_offset = tern_op_end_offset; 77 | ctx->expr_diag.pop(); 78 | 79 | // breaks invalid print optimization 80 | generate(ctx); 81 | } 82 | 83 | } // namespace Parser 84 | } // namespace Teng 85 | 86 | -------------------------------------------------------------------------------- /src/udf.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * 25 | * DESCRIPTION 26 | * Teng processor function (like len, round or formatDate) 27 | * 28 | * AUTHORS 29 | * Jan Nemec 30 | * Vaclav Blazek 31 | * Michal Bukovsky 32 | * 33 | * HISTORY 34 | * 2003-09-26 (jan) 35 | * Created. 36 | * 2018-06-07 (burlog) 37 | * Rewrite to C++. 38 | */ 39 | 40 | #include 41 | #include 42 | 43 | #include "platform.h" 44 | #include "teng/udf.h" 45 | 46 | namespace Teng { 47 | namespace udf { 48 | namespace { 49 | 50 | /** Functions registry. 51 | */ 52 | class Registry_t { 53 | public: 54 | /** Returns registered function for given name if any or empty function. 55 | */ 56 | Function_t find(const std::string &name) { 57 | #ifndef NO_UDF_LOCKS 58 | std::lock_guard locked(mutex); 59 | #endif /* NO_UDF_LOCKS */ 60 | auto ifunction = registry.find(name); 61 | return ifunction == registry.end() 62 | ? Function_t{} 63 | : ifunction->second; 64 | } 65 | 66 | /** Inserts new value to registry. 67 | */ 68 | void insert(const std::string &name, Function_t function) { 69 | #ifndef NO_UDF_LOCKS 70 | std::lock_guard locked(mutex); 71 | #endif /* NO_UDF_LOCKS */ 72 | registry.emplace("udf." + name, std::move(function)); 73 | } 74 | 75 | /** D'tor 76 | */ 77 | ~Registry_t() { 78 | #ifndef NO_UDF_LOCKS 79 | std::lock_guard locked(mutex); 80 | #endif /* NO_UDF_LOCKS */ 81 | registry.clear(); 82 | } 83 | 84 | std::mutex mutex; 85 | std::unordered_map registry; 86 | } registered_functions; 87 | 88 | } // namespace 89 | 90 | void registerFunction(const std::string &name, Function_t function) { 91 | registered_functions.insert(name, std::move(function)); 92 | } 93 | 94 | Invoker_t findFunction(const std::string &name) { 95 | return {name, registered_functions.find(name)}; 96 | } 97 | 98 | } // namespace udf 99 | } // namespace Teng 100 | 101 | -------------------------------------------------------------------------------- /src/semantic.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTIC_H 40 | #define TENGSEMANTIC_H 41 | 42 | #include 43 | 44 | namespace Teng { 45 | 46 | // forwards 47 | struct Pos_t; 48 | class Regex_t; 49 | class Value_t; 50 | struct Identifier_t; 51 | 52 | namespace Parser { 53 | 54 | // forwards 55 | class Token_t; 56 | struct Context_t; 57 | class Options_t; 58 | class Literal_t; 59 | class Variable_t; 60 | class NAryExpr_t; 61 | struct VarOffset_t; 62 | enum class diag_code; 63 | 64 | /** Saves error position for further processing. 65 | */ 66 | Token_t note_error(Context_t *ctx, const Token_t &token); 67 | 68 | /** Clears last stored error. 69 | */ 70 | void reset_error(Context_t *ctx); 71 | 72 | /** Generates instruction for given value. 73 | */ 74 | void generate_val(Context_t *ctx, const Pos_t &pos, Value_t value); 75 | 76 | /** Inserts new diagnostic code into diag-codes storage. If pop is set to true 77 | * then the previous diagnostic code is poped out. 78 | * 79 | * The diagnostic codes are used to help the template writer where the syntax 80 | * error probably is. 81 | */ 82 | void expr_diag(Context_t *ctx, diag_code new_diag_code, bool pop = true); 83 | 84 | /** Inserts new diagnostic code into diag-codes storage including the diag code 85 | * sentinel. 86 | */ 87 | void expr_diag_sentinel(Context_t *ctx, diag_code new_diag_code); 88 | 89 | /** Generates given instruction pass given args to instruction c'tor. 90 | */ 91 | template 92 | void generate(Ctx_t *ctx, Args_t &&...args) { 93 | ctx->program->template emplace_back(std::forward(args)...); 94 | } 95 | 96 | } // namespace Parser 97 | } // namespace Teng 98 | 99 | #endif /* TENGSEMANTIC_H */ 100 | 101 | -------------------------------------------------------------------------------- /src/openframesapi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengfragmentstack.h,v 1.7 2006-06-13 10:04:16 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng open fragments frames API. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-07-07 (burlog) 34 | * Created. 35 | */ 36 | 37 | #ifndef TENGOPENFRAMESAPI_H 38 | #define TENGOPENFRAMESAPI_H 39 | 40 | #include 41 | 42 | #include "teng/value.h" 43 | 44 | namespace Teng { 45 | 46 | /** This structure is control flow exception, that is used when some 47 | * instruction implementation encounters the state that can't be processed 48 | * with instance of EvalCtx_t and it needs the RunCtx_t to continue. 49 | */ 50 | struct runtime_ctx_needed_t {}; 51 | 52 | /** The API that implements common functionality accessing of fragments. It is 53 | * used to simulate fragmnets tree during parsing to allow expression 54 | * optimalizer optimalize exressions. 55 | */ 56 | struct OFFApi_t { 57 | /** D'tor. 58 | */ 59 | virtual ~OFFApi_t() noexcept = default; 60 | 61 | /** Returns fragment/value at given open frame/fragments offsets. 62 | */ 63 | virtual Value_t 64 | value_at(uint64_t frame_offset, uint64_t frag_offset) const = 0; 65 | 66 | /** Returns fragment value of desired name. 67 | */ 68 | virtual Value_t 69 | value_at(const Value_t &, const string_view_t &, std::size_t &) const = 0; 70 | 71 | /** Returns fragment/list value of desire name/index. 72 | */ 73 | virtual Value_t 74 | value_at(const Value_t &, const Value_t &, std::size_t &) const = 0; 75 | 76 | /** Returns names of open fragments in current frame joined by dots. 77 | */ 78 | virtual std::string current_path() const = 0; 79 | 80 | /** Returns index of the current fragmnet in current opened fragment list. 81 | */ 82 | virtual std::size_t current_list_i() const = 0; 83 | 84 | /** Returns size of the current fragmnet list. 85 | */ 86 | virtual std::size_t current_list_size() const = 0; 87 | 88 | /** Returns true if value is not "undefined" value. 89 | */ 90 | virtual Value_t exists(const Value_t &) const = 0; 91 | }; 92 | 93 | } // namespace Teng 94 | 95 | #endif /* TENGOPENFRAMESAPI_H */ 96 | 97 | -------------------------------------------------------------------------------- /src/semanticexpr.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICEXPR_H 40 | #define TENGSEMANTICEXPR_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Saves the point where expression begins. 50 | */ 51 | void note_expr_start_point(Context_t *ctx, const Pos_t &pos); 52 | 53 | /** Saves the highest valid address (program->size() - 1) as possible 54 | * optimization point. 55 | */ 56 | void note_optimization_point(Context_t *ctx, bool optimizable); 57 | 58 | /** Attempts to optimize expression during compile time. (NOT TRUE -> FALSE) 59 | */ 60 | void optimize_expr(Context_t *ctx, uint32_t arity, bool lazy_evaluated = false); 61 | 62 | /** Discards all instructions generated by valid part of invalid expression and 63 | * restore context to valid state. 64 | */ 65 | void discard_expr(Context_t *ctx); 66 | 67 | /** Cleanes used resources for building exprs. 68 | */ 69 | void finish_expr(Context_t *ctx); 70 | 71 | /** Prepares new expression. 72 | */ 73 | void prepare_expr(Context_t *ctx, const Pos_t &pos); 74 | 75 | /** Generates expression from given symbol. 76 | */ 77 | uint32_t 78 | generate_str_expr(Context_t *ctx, const Token_t &token, bool negate = false); 79 | 80 | /** Generates binary operator AND. 81 | */ 82 | void generate_bin_and(Context_t *ctx, const Token_t &token); 83 | 84 | /** Finalizes binary operator AND. 85 | */ 86 | void finalize_bin_and(Context_t *ctx); 87 | 88 | /** Generates binary operator OR. 89 | */ 90 | void generate_bin_or(Context_t *ctx, const Token_t &token); 91 | 92 | /** Finalizes binary operator OR. 93 | */ 94 | void finalize_bin_or(Context_t *ctx); 95 | 96 | /** Generates expression from given symbol. 97 | */ 98 | template 99 | void generate_expr(Context_t *ctx, const Token_t &token) { 100 | generate(ctx, token.pos); 101 | } 102 | 103 | } // namespace Parser 104 | } // namespace Teng 105 | 106 | #endif /* TENGSEMANTICEXPR_H */ 107 | 108 | -------------------------------------------------------------------------------- /src/semanticif.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICIF_H 40 | #define TENGSEMANTICIF_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Prepares new if statement. 50 | */ 51 | void prepare_if_stmnt(Context_t *ctx, const Pos_t &pos); 52 | 53 | /** Cleans after if statement building. 54 | */ 55 | void finalize_if_stmnt(Context_t *ctx); 56 | 57 | /** Generates instructions implementing the if expression. 58 | */ 59 | void generate_if(Context_t *ctx, const Token_t &token, bool valid_expr); 60 | 61 | /** Generates instructions implementing the if expression. 62 | */ 63 | void generate_if(Context_t *ctx, const Token_t &token, const Token_t &inv); 64 | 65 | /** Updates branch terminating jumps. 66 | */ 67 | void generate_endif(Context_t *ctx, const Pos_t *inv_pos = nullptr); 68 | 69 | /** Cleans after invalid if statement building. 70 | */ 71 | void finalize_inv_if_stmnt(Context_t *ctx, const Token_t &token); 72 | 73 | /** Generates instructions implementing the else expression. 74 | */ 75 | void generate_else(Context_t *ctx, const Token_t &token, bool invalid = false); 76 | 77 | /** Calculates if expression's jump and updates appropriate instructions in 78 | * program. 79 | */ 80 | void prepare_elif(Context_t *ctx, const Token_t &token); 81 | 82 | /** Discards while if statement because of invalid order of else/elif branches. 83 | */ 84 | void discard_if_stmnt(Context_t *ctx); 85 | 86 | /** Generates instructions implementing the if expression. 87 | */ 88 | inline void 89 | generate_elif(Context_t *ctx, const Token_t &token, bool valid_expr) { 90 | generate_if(ctx, token, valid_expr); 91 | } 92 | 93 | /** Generates instructions implementing the if expression. 94 | */ 95 | inline void 96 | generate_elif(Context_t *ctx, const Token_t &token, const Token_t &inv) { 97 | generate_if(ctx, token, inv); 98 | } 99 | 100 | } // namespace Parser 101 | } // namespace Teng 102 | 103 | #endif /* TENGSEMANTICIF_H */ 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/fragmentlist.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengstructs.cc,v 1.4 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng data types -- implementation. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-30 (vasek) 34 | * Created. 35 | * 2005-06-21 (roman) 36 | * Win32 support. 37 | */ 38 | 39 | #include "jsonutils.h" 40 | #include "teng/fragmentvalue.h" 41 | #include "teng/fragmentlist.h" 42 | #include "teng/fragment.h" 43 | 44 | namespace Teng { 45 | 46 | Fragment_t &FragmentList_t::addFragment() { 47 | items.emplace_back(TypeTag_t()); 48 | return items.back().frag_value; 49 | } 50 | 51 | FragmentList_t &FragmentList_t::addFragmentList() { 52 | items.emplace_back(TypeTag_t()); 53 | return items.back().list_value; 54 | } 55 | 56 | void FragmentList_t::addValue(const std::string &value) { 57 | items.emplace_back(value); 58 | } 59 | 60 | void FragmentList_t::addIntValue(IntType_t value) { 61 | items.emplace_back(value); 62 | } 63 | 64 | void FragmentList_t::addRealValue(double value) { 65 | items.emplace_back(value); 66 | } 67 | 68 | void FragmentList_t::addValue(Fragment_t &&value) { 69 | items.emplace_back(std::move(value)); 70 | } 71 | 72 | void FragmentList_t::addValue(FragmentList_t &&value) { 73 | items.emplace_back(std::move(value)); 74 | } 75 | 76 | void FragmentList_t::addValue(FragmentValue_t &&value) { 77 | items.emplace_back(std::move(value)); 78 | } 79 | 80 | void FragmentList_t::json(std::ostream &o) const { 81 | o << '['; 82 | for (auto ifrag = begin(), efrag = end(); ifrag != efrag; ++ifrag) { 83 | if (ifrag != begin()) o << ", "; 84 | ifrag->json(o); 85 | } 86 | o << ']'; 87 | } 88 | 89 | FragmentList_t::size_type FragmentList_t::size() const { 90 | return items.size(); 91 | } 92 | 93 | void FragmentList_t::dump(std::ostream &o) const { 94 | o << '['; 95 | for (auto ifrag = begin(), efrag = end(); ifrag != efrag; ++ifrag) { 96 | if (ifrag != begin()) o << ", "; 97 | ifrag->dump(o); 98 | } 99 | o << ']'; 100 | } 101 | 102 | const FragmentValue_t &FragmentList_t::operator[](size_type i) const { 103 | return items[i]; 104 | } 105 | 106 | FragmentValue_t &FragmentList_t::operator[](size_type i) { 107 | return items[i]; 108 | } 109 | 110 | } // namespace Teng 111 | 112 | -------------------------------------------------------------------------------- /src/semanticblock.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICBLOCK_H 40 | #define TENGSEMANTICBLOCK_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Generates instructions implementing format switching. 50 | */ 51 | void open_format(Context_t *ctx, const Pos_t &pos, const Options_t &opts); 52 | 53 | /** Generates instructions implementing format switching. 54 | */ 55 | void open_inv_format(Context_t *ctx, const Pos_t &pos); 56 | 57 | /** Generates instructions that restore previous (or default) format. 58 | */ 59 | void close_format(Context_t *ctx, const Pos_t &pos); 60 | 61 | /** Generates instructions that restore previous (or default) format and 62 | * reports invalid token. 63 | */ 64 | void close_inv_format(Context_t *ctx, const Pos_t &pos); 65 | 66 | /** Generates instructions that restore previous (or default) format and 67 | * reports missing close format directive. 68 | */ 69 | void 70 | close_unclosed_format(Context_t *ctx, const Pos_t &pos, const Token_t &token); 71 | 72 | /** Generates instructions implementing content type switching. 73 | */ 74 | void open_ctype(Context_t *ctx, const Pos_t &pos, const Literal_t &type); 75 | 76 | /** Generates instructions implementing content type switching. 77 | */ 78 | void open_inv_ctype(Context_t *ctx, const Pos_t &pos); 79 | 80 | /** Generates instructions that restore previous (or default) content type. 81 | */ 82 | void close_ctype(Context_t *ctx, const Pos_t &pos); 83 | 84 | /** Generates instructions that restore previous (or default) content type and 85 | * reports invalid token. 86 | */ 87 | void close_inv_ctype(Context_t *ctx, const Pos_t &pos); 88 | 89 | /** Generates instructions that restore previous (or default) content type and 90 | * reports missing close content type directive. 91 | */ 92 | void 93 | close_unclosed_ctype(Context_t *ctx, const Pos_t &pos, const Token_t &token); 94 | 95 | } // namespace Parser 96 | } // namespace Teng 97 | 98 | #endif /* TENGSEMANTICBLOCK_H */ 99 | 100 | -------------------------------------------------------------------------------- /src/parserdiag.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengparsercontext.h,v 1.5 2006-10-18 08:31:09 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng parser diagnostic codes. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 41 | #include 42 | #include 43 | #include 44 | 45 | #include "position.h" 46 | 47 | namespace Teng { 48 | namespace Parser { 49 | 50 | /** Possible diagnostic codes. 51 | */ 52 | enum class diag_code { 53 | sentinel, 54 | case_cond, 55 | case_option, 56 | case_option_branch, 57 | case_default_branch, 58 | tern_colon, 59 | tern_true_branch, 60 | tern_false_branch, 61 | fun_args, 62 | }; 63 | 64 | // shortcuts 65 | class Token_t; 66 | struct Context_t; 67 | using Addresses_t = std::vector; 68 | using diag_code_type = diag_code; 69 | 70 | /** Diagnostic codes entry that describes what happened. 71 | */ 72 | struct ExprDiagEntry_t { 73 | bool is_sentinel() {return code == diag_code::sentinel;} 74 | void log_case(Context_t *ctx, const Token_t &token); 75 | void log_tern(Context_t *ctx, const Token_t &token); 76 | void log(Context_t *ctx, const Token_t &token); 77 | diag_code_type code; //!< the code value 78 | Pos_t pos; //!< pos to corresponding token 79 | }; 80 | 81 | /** Diagnostic codes are technique to help template writer better understand 82 | * where the syntax error is. Appropriate diagnostic code is pushed before 83 | * every diagnosed syntax symbol and popped out after it is properly parsed. 84 | * If some will remain in this list it means that some complex expression is 85 | * incorrectly formed. 86 | */ 87 | struct ExprDiag_t { 88 | void unwind(Context_t *ctx, const Token_t &token); 89 | void pop() {entries.pop_back();} 90 | void push(ExprDiagEntry_t entry) {entries.push_back(std::move(entry));} 91 | void push_sentinel() {push({diag_code::sentinel, {}});} 92 | static void log_unexpected_token(Context_t *ctx); 93 | std::size_t size() const {return entries.size();} 94 | void clear() {entries.clear();} 95 | std::vector entries; //!< list of diagnostic codes 96 | }; 97 | 98 | } // namespace Parser 99 | } // namespace Teng 100 | 101 | #endif /* TENGPARSERDIAG_H */ 102 | 103 | -------------------------------------------------------------------------------- /src/hex.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tenghex.cc,v 1.18 2008-11-20 23:32:29 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Hexadecimal encoding of bytes. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-14 (burlog) 34 | * Created. 35 | */ 36 | 37 | #include "hex.h" 38 | 39 | namespace Teng { 40 | 41 | const uint8_t hex_values[256] = { 42 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 - 7 43 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8 - 15 44 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 16 - 23 45 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 24 - 31 46 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 32 - 39 47 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 40 - 47 48 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 48 - 55 49 | 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 56 - 63 50 | 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // 64 - 71 51 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 72 - 79 52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 53 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 95 54 | 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, // 96 - 103 55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 104 - 111 56 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 112 - 119 57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 120 - 127 58 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 128 - 135 59 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 136 - 143 60 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 144 - 151 61 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 152 - 159 62 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 160 - 167 63 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 168 - 175 64 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 176 - 183 65 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 184 - 191 66 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 192 - 199 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 200 - 207 68 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 208 - 215 69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 216 - 223 70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 224 - 231 71 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 232 - 239 72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 240 - 247 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 248 - 255 74 | }; 75 | 76 | } // namespace Teng 77 | 78 | -------------------------------------------------------------------------------- /src/semanticregex.cc: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #include "debug.h" 40 | #include "regex.h" 41 | #include "syntax.hh" 42 | #include "logging.h" 43 | #include "instruction.h" 44 | #include "parsercontext.h" 45 | #include "semanticregex.h" 46 | 47 | namespace Teng { 48 | namespace Parser { 49 | 50 | counted_ptr generate_regex(Context_t *ctx, const Token_t ®ex) { 51 | regex_flags_t flags; 52 | auto i = regex.view().size() - 1; 53 | for (; regex.view()[i] != '/'; --i) { 54 | switch (regex.view()[i]) { 55 | case 'i': flags->ignore_case = true; break; 56 | case 'g': flags->global = true; break; 57 | case 'm': flags->multiline = true; break; 58 | case 'e': flags->extended = true; break; 59 | case 'X': flags->extra = true; break; 60 | case 'U': flags->ungreedy = true; break; 61 | case 'A': flags->anchored = true; break; 62 | case 'D': flags->dollar_endonly = true; break; 63 | default: 64 | logWarning( 65 | ctx, 66 | regex.pos, 67 | "Ignoring unknown regex flag '" 68 | + std::string(1, regex.view()[i]) 69 | + "'" 70 | ); 71 | } 72 | } 73 | 74 | try { 75 | auto *data = regex.view().data(); 76 | string_view_t pattern = {data + 1, data + i}; 77 | return make_counted(pattern, flags); 78 | 79 | } catch (const std::exception &e) { 80 | logWarning( 81 | ctx, 82 | regex.pos, 83 | std::string("Invalid regular expression: ") + e.what() 84 | ); 85 | } 86 | return make_counted(".^", flags); 87 | } 88 | 89 | void 90 | generate_match(Context_t *ctx, const Token_t &token, const Token_t ®ex) { 91 | // parse regex (split pattern and flags) 92 | auto regex_value = generate_regex(ctx, regex); 93 | 94 | // generate instruction for parsed regex 95 | generate(ctx, std::move(regex_value), regex.pos); 96 | if (token == LEX2::STR_NE) 97 | generate(ctx, token.pos); 98 | } 99 | 100 | } // namespace Parser 101 | } // namespace Teng 102 | 103 | -------------------------------------------------------------------------------- /src/sourcelist.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengsourcelist.h,v 1.2 2004-12-30 12:42:02 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng list of sources. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-23 (vasek) 34 | * Created. 35 | */ 36 | 37 | 38 | #ifndef TENGSOURCELIST_H 39 | #define TENGSOURCELIST_H 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | #include "position.h" 47 | #include "teng/error.h" 48 | #include "teng/filesystem.h" 49 | 50 | namespace Teng { 51 | 52 | /** 53 | * @short Holds statistic about file (see stat(2)). 54 | * 55 | * Used for detection of content change. 56 | */ 57 | struct FileStat_t { 58 | std::string filename; //!< name of associated file 59 | size_t hash; //!< hash of file statistic. 60 | }; 61 | 62 | /** 63 | * @short List of source files. 64 | */ 65 | class SourceList_t { 66 | public: 67 | /** @short Creates new (empty) source list. 68 | */ 69 | SourceList_t(): sources() {} 70 | 71 | /** @short Adds new source into the list. 72 | * 73 | * @param source filename of source 74 | * 75 | * @return index of added source in list 76 | */ 77 | std::pair push(const FilesystemInterface_t* filesystem, std::string filename); 78 | 79 | /** @short Check validity of all sources. 80 | * 81 | * Stats files and compares current data with cached. 82 | * 83 | * @return true means modified; false not modified or error 84 | */ 85 | bool isChanged(const FilesystemInterface_t* filesystem) const; 86 | 87 | /** @short Get source by given index. 88 | * 89 | * @param position index in the source list 90 | * @return filename or empty string on error 91 | */ 92 | const std::string *operator[](std::size_t i) const; 93 | 94 | /** @short Returns the number of sources. 95 | */ 96 | std::size_t size() const {return sources.size();} 97 | 98 | /** @short Returns iterator to the first source. 99 | */ 100 | auto begin() const {return sources.begin();} 101 | 102 | /** @short Returns iterator one past the last source. 103 | */ 104 | auto end() const {return sources.end();} 105 | 106 | private: 107 | // don't copy 108 | SourceList_t(const SourceList_t &) = delete; 109 | SourceList_t &operator=(const SourceList_t &) = delete; 110 | 111 | std::vector> sources; //!< list of sources/files 112 | }; 113 | 114 | } // namespace Teng 115 | 116 | #endif // TENGSOURCELIST_H 117 | 118 | -------------------------------------------------------------------------------- /src/logging.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengerror.h,v 1.6 2011-01-19 06:39:45 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng error logging. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-14 (burlog) 34 | * Created. 35 | */ 36 | 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "program.h" 43 | #include "parsercontext.h" 44 | #include "yystype.h" 45 | #include "logging.h" 46 | 47 | namespace Teng { 48 | 49 | void 50 | logError( 51 | Error_t &err, 52 | Error_t::Level_t level, 53 | const Pos_t &pos, 54 | const string_view_t &msg 55 | ) { 56 | err.append(level, pos.filename, pos.lineno, pos.colno, msg.str()); 57 | } 58 | 59 | void 60 | logDebug(Error_t &err, const Pos_t &pos, const string_view_t &msg) { 61 | logError(err, Error_t::DEBUGING, pos, msg); 62 | } 63 | 64 | void 65 | logWarning(Error_t &err, const Pos_t &pos, const string_view_t &msg) { 66 | logError(err, Error_t::WARNING, pos, msg); 67 | } 68 | 69 | void 70 | logError(Error_t &err, const Pos_t &pos, const string_view_t &msg) { 71 | logError(err, Error_t::ERROR, pos, msg); 72 | } 73 | 74 | void 75 | logFatal(Error_t &err, const Pos_t &pos, const string_view_t &msg) { 76 | logError(err, Error_t::FATAL, pos, msg); 77 | } 78 | 79 | void 80 | logDebug(Error_t &err, const string_view_t &msg) { 81 | logError(err, Error_t::DEBUGING, msg); 82 | } 83 | 84 | void 85 | logWarning(Error_t &err, const string_view_t &msg) { 86 | logError(err, Error_t::WARNING, msg); 87 | } 88 | 89 | void 90 | logError(Error_t &err, const string_view_t &msg) { 91 | logError(err, Error_t::ERROR, msg); 92 | } 93 | 94 | void 95 | logFatal(Error_t &err, const string_view_t &msg) { 96 | logError(err, Error_t::FATAL, msg); 97 | } 98 | 99 | namespace Parser { 100 | 101 | void 102 | logWarning(Context_t *ctx, const Pos_t &pos, const string_view_t &msg) { 103 | logError(ctx->program->getErrors(), Error_t::WARNING, pos, msg); 104 | } 105 | 106 | void 107 | logDiag(Context_t *ctx, const Pos_t &pos, const string_view_t &msg) { 108 | logError(ctx->program->getErrors(), Error_t::DIAG, pos, msg); 109 | } 110 | 111 | void 112 | logError(Context_t *ctx, const Pos_t &pos, const string_view_t &msg) { 113 | logError(ctx->program->getErrors(), Error_t::ERROR, pos, msg); 114 | } 115 | 116 | void 117 | logFatal(Context_t *ctx, const Pos_t &pos, const string_view_t &msg) { 118 | logError(ctx->program->getErrors(), Error_t::FATAL, pos, msg); 119 | } 120 | 121 | } // namespace Parser 122 | } // namespace Teng 123 | 124 | -------------------------------------------------------------------------------- /src/logging.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengerror.h,v 1.6 2011-01-19 06:39:45 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng error logging. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-14 (burlog) 34 | * Created. 35 | */ 36 | 37 | #ifndef TENGLOGGING_H 38 | #define TENGLOGGING_H 39 | 40 | #include "position.h" 41 | #include "teng/error.h" 42 | #include "teng/stringview.h" 43 | 44 | namespace Teng { 45 | 46 | /** @short Logs new error. 47 | * @param pos position in file 48 | * @param msg additional message 49 | */ 50 | void 51 | logError(Error_t &err, 52 | Error_t::Level_t level, 53 | const Pos_t &pos, 54 | const string_view_t &msg); 55 | 56 | /** @short Logs DEBUGGING for given file/position. 57 | */ 58 | void 59 | logDebug(Error_t &err, const Pos_t &pos, const string_view_t &msg); 60 | 61 | /** @short Logs WARNING for given file/position. 62 | */ 63 | void 64 | logWarning(Error_t &err, const Pos_t &pos, const string_view_t &msg); 65 | 66 | /** @short Logs ERROR for given file/position. 67 | */ 68 | void 69 | logError(Error_t &err, const Pos_t &pos, const string_view_t &msg); 70 | 71 | /** @short Logs FATAL for given file/position. 72 | */ 73 | void 74 | logFatal(Error_t &err, const Pos_t &pos, const string_view_t &msg); 75 | 76 | /** @short Logs DEBUGGING for given file/position. 77 | */ 78 | void 79 | logDebug(Error_t &err, const string_view_t &msg); 80 | 81 | /** @short Logs WARNING for given file/position. 82 | */ 83 | void 84 | logWarning(Error_t &err, const string_view_t &msg); 85 | 86 | /** @short Logs ERROR for given file/position. 87 | */ 88 | void 89 | logError(Error_t &err, const string_view_t &msg); 90 | 91 | /** @short Logs FATAL for given file/position. 92 | */ 93 | void 94 | logFatal(Error_t &err, const string_view_t &msg); 95 | 96 | namespace Parser { 97 | 98 | // forwards 99 | struct Context_t; 100 | 101 | /** @short Logs WARNING for given file/position. 102 | */ 103 | void logWarning(Context_t *ctx, const Pos_t &pos, const string_view_t &msg); 104 | 105 | /** @short Logs DIAG for given file/position. 106 | */ 107 | void logDiag(Context_t *ctx, const Pos_t &pos, const string_view_t &msg); 108 | 109 | /** @short Logs ERROR for given file/position. 110 | */ 111 | void logError(Context_t *ctx, const Pos_t &pos, const string_view_t &msg); 112 | 113 | /** @short Logs FATAL for given file/position. 114 | */ 115 | void logFatal(Context_t *ctx, const Pos_t &pos, const string_view_t &msg); 116 | 117 | } // namespace Parser 118 | } // namespace Teng 119 | 120 | #endif // TENGLOGGING_H 121 | 122 | -------------------------------------------------------------------------------- /src/processor.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengprocessor.h,v 1.3 2005-04-26 13:56:25 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng processor. Executes programs. 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Vaclav Blazek 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2003-09-22 (jan) 36 | * Created. 37 | * 2004-05-30 (vasek) 38 | * Revised processor source code. 39 | * 2004-09-19 (vasek) 40 | * Some minor fixes. 41 | */ 42 | 43 | #ifndef TENGPROCESSOR_H 44 | #define TENGPROCESSOR_H 45 | 46 | #include 47 | 48 | #include "teng/stringview.h" 49 | 50 | namespace Teng { 51 | 52 | // forwards 53 | class Error_t; 54 | class Value_t; 55 | class Writer_t; 56 | struct OFFApi_t; 57 | class Program_t; 58 | class FragmentValue_t; 59 | class Dictionary_t; 60 | class Configuration_t; 61 | class ContentType_t; 62 | 63 | /** Does the template interpretation. 64 | */ 65 | class Processor_t { 66 | public: 67 | /** Inititalize processor. 68 | * 69 | * @param err Error log object. 70 | * @param program Program in byte-code to interpret. 71 | * @param dict Language dictionary. 72 | * @param params Language-independent dictionaru (param.conf). 73 | * @param encoding Template encoding. 74 | * @param contentType Content type of template. 75 | */ 76 | Processor_t( 77 | Error_t &err, 78 | const Program_t &program, 79 | const Dictionary_t &dict, 80 | const Configuration_t ¶ms, 81 | const string_view_t &encoding = "utf-8", 82 | const string_view_t &contentType = {} 83 | ); 84 | 85 | /** Execute program. 86 | * 87 | * @param data Application data supplied by user. 88 | * @param writer Output stream object. 89 | */ 90 | void run(const FragmentValue_t &data, Writer_t &writer); 91 | 92 | /** Try to evaluate an expression. 93 | * 94 | * @param startAddress Run program from this address. 95 | */ 96 | Value_t eval(const OFFApi_t *frames, int64_t start); 97 | 98 | protected: 99 | Error_t &err; //!< error log object 100 | const Program_t &program; //!< program (translated template) 101 | const Dictionary_t &dict; //!< language specific dictionary 102 | const Configuration_t ¶ms; //!< param dictionary 103 | string_view_t encoding; //!< the template charset 104 | string_view_t contentType; //!< the template content/mime type 105 | }; 106 | 107 | } // namespace Teng 108 | 109 | #endif // TENGPROCESSOR_H 110 | 111 | -------------------------------------------------------------------------------- /src/semanticinheritance.h: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #ifndef TENGSEMANTICINHERITANCE_H 40 | #define TENGSEMANTICINHERITANCE_H 41 | 42 | #include 43 | 44 | #include "semantic.h" 45 | 46 | namespace Teng { 47 | namespace Parser { 48 | 49 | /** Compiles the base template which this one extends. 50 | */ 51 | void extends_file(Context_t *ctx, const Pos_t &pos, const Options_t &opts); 52 | 53 | /** Writes warning into log error about ignored extends. 54 | */ 55 | void ignore_extends(Context_t *ctx, const Token_t &token, bool empty = false); 56 | 57 | /** Close list of overriding blocks. 58 | */ 59 | void close_extends(Context_t *ctx, const Pos_t *inv_pos = nullptr); 60 | 61 | /** Starts overridden block. 62 | */ 63 | void note_override_block(Context_t *ctx, const Token_t &ident); 64 | 65 | /** Registers overridden block into the overridden block registry of this 66 | * extends block. 67 | */ 68 | void reg_override_block(Context_t *ctx, const Token_t &end_block); 69 | 70 | /** Starts generating the base implementation of this overridden block. 71 | */ 72 | void note_define_block(Context_t *ctx, const Token_t &ident); 73 | 74 | /** Warns that this define block token is invalid. 75 | */ 76 | void note_inv_define_block(Context_t *ctx, const Token_t &define_block); 77 | 78 | /** Registers overridden block into the overridden block registry of this 79 | * extends block and starts generating the overrides. 80 | */ 81 | void reg_define_block(Context_t *ctx, const Token_t &end_block); 82 | 83 | /** Generates CALL instruction that calls the parent block implementation. 84 | */ 85 | void call_super_block(Context_t *ctx, const Token_t &super_block); 86 | 87 | /** The override directive out of extends block. 88 | */ 89 | void ignore_free_override(Context_t *ctx, const Token_t &token); 90 | 91 | /** Tells the user that extends block is unclosed. 92 | */ 93 | void ignore_unclosed_extends(Context_t *ctx, const Token_t &token); 94 | 95 | /** Warns that this override block token is invalid. 96 | */ 97 | void note_inv_override_block(Context_t *ctx, const Token_t &override_block); 98 | 99 | /** Closes unclosed define block and generate warning. 100 | */ 101 | void unclosed_define_block(Context_t *ctx, const Token_t &token); 102 | 103 | } // namespace Parser 104 | } // namespace Teng 105 | 106 | #endif /* TENGSEMANTICINHERITANCE_H */ 107 | 108 | -------------------------------------------------------------------------------- /src/filesystem.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004-2018 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "teng/filesystem.h" 29 | #include "platform.h" 30 | #include "util.h" 31 | 32 | namespace Teng { 33 | 34 | static std::string makeFilename(const std::string& root, const std::string& filename_) 35 | { 36 | std::string filename = 37 | (!root.empty() && !filename_.empty() && filename_[0] != '/') 38 | ? root + "/" + filename_ 39 | : filename_; 40 | 41 | normalizeFilename(filename); 42 | return filename; 43 | } 44 | 45 | template 46 | static void hashCombine(std::size_t& seed, S const& value) 47 | { 48 | std::size_t hash = std::hash{}(value); 49 | seed ^= hash + 0x9e3779b9 + (seed<<6) + (seed>>2); // or use boost::hash_combine 50 | } 51 | 52 | Filesystem_t::Filesystem_t(const std::string& root_) 53 | : root(root_) 54 | { 55 | // if not absolute path, prepend current working directory 56 | if (root.empty() || !ISROOT(root)) { 57 | char cwd[2048]; 58 | if (!getcwd(cwd, sizeof(cwd))) { 59 | throw std::runtime_error("Cannot get cwd."); 60 | } 61 | root = std::string(cwd) + '/' + root; 62 | } 63 | } 64 | 65 | std::string Filesystem_t::read(const std::string& filename_) const 66 | { 67 | std::string result; 68 | 69 | std::string filename = makeFilename(root, filename_); 70 | 71 | std::ifstream file(filename.c_str(), std::ios::binary | std::ios::in); 72 | if (!file) { 73 | throw std::runtime_error("Cannot open file '" + filename + "'"); 74 | } 75 | 76 | // read whole file into memory 77 | file.seekg(0, std::ios::end); 78 | result.resize(file.tellg()); 79 | file.seekg(0, std::ios::beg); 80 | file.read(&result[0], result.size()); 81 | 82 | if (!file) { 83 | throw std::runtime_error("Failed to read file '" + filename + "'"); 84 | } 85 | 86 | return result; 87 | } 88 | 89 | size_t Filesystem_t::hash(const std::string& filename_) const 90 | { 91 | std::size_t seed = 0; 92 | 93 | std::string filename = makeFilename(root, filename_); 94 | 95 | // stat given file 96 | struct stat buf; 97 | if (::stat(filename.c_str(), &buf)) { 98 | throw std::runtime_error("Cannot stat file '" + filename + "'"); 99 | } 100 | 101 | // check if not dir 102 | if (S_ISDIR(buf.st_mode)) { 103 | throw std::runtime_error("File '" + filename + "' is a directory"); 104 | } 105 | 106 | hashCombine(seed, buf.st_ino); // unsigned long int - inode number 107 | hashCombine(seed, buf.st_size); // long - total size, in bytes 108 | hashCombine(seed, buf.st_mtime); // long - time of last modification 109 | hashCombine(seed, buf.st_ctime); // long - time of last status change 110 | 111 | return seed; 112 | } 113 | 114 | } // namespace Teng 115 | -------------------------------------------------------------------------------- /tests/fuzz.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: $ 25 | * 26 | * DESCRIPTION 27 | * Teng engine -- fuzzer main. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-11-30 (burlog) 34 | * Created. 35 | */ 36 | 37 | #include 38 | #include 39 | 40 | #include 41 | 42 | extern "C" { 43 | 44 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { 45 | std::string string(reinterpret_cast(data), size); 46 | 47 | std::string result; 48 | Teng::Teng_t teng; 49 | Teng::Error_t err; 50 | Teng::StringWriter_t writer(result); 51 | 52 | Teng::Fragment_t root; 53 | auto &data_frag = root.addFragment("data"); 54 | data_frag.addFragment("current_section"); 55 | data_frag.addVariable("a", "123"); 56 | data_frag.addVariable("b", -1); 57 | data_frag.addVariable("c", 0); 58 | for (int i = 0; i < 3; ++i) { 59 | auto &sub_frag = data_frag.addFragment("subsections"); 60 | sub_frag.addVariable("thread_count", i); 61 | sub_frag.addVariable("icon_url", "http:://icon.url"); 62 | sub_frag.addVariable("a", "123"); 63 | sub_frag.addVariable("b", -1); 64 | sub_frag.addVariable("c", 0); 65 | for (int j = 0; j < 3; ++j) { 66 | auto &n_frag = sub_frag.addFragment("topNThreads"); 67 | n_frag.addVariable("answer_count", 10); 68 | n_frag.addVariable("a", "123"); 69 | n_frag.addVariable("b", -1); 70 | n_frag.addVariable("c", 0); 71 | if (j > 1) { 72 | auto &profile_frag = n_frag.addFragment("profile"); 73 | profile_frag.addVariable("image", "aaa"); 74 | } 75 | } 76 | } 77 | 78 | Teng::Teng_t::GenPageArgs_t args; 79 | args.contentType = "text/html"; 80 | args.encoding = "utf-8"; 81 | args.templateString = std::move(string); 82 | 83 | teng.generatePage(args, root, writer, err); 84 | return 0; 85 | } 86 | 87 | } // extern "C" 88 | 89 | #ifdef FUZZ_MAIN 90 | 91 | int main(int argc, char *argv[]) { 92 | if (argc <= 1) { 93 | std::cerr << "Usage: ./fuzz artifact-file" << std::endl; 94 | return -1; 95 | } 96 | std::ifstream artifact(argv[1]); 97 | if (!artifact) { 98 | std::cerr << "can't open file: " << argv[1] << std::endl; 99 | return -2; 100 | } 101 | 102 | std::string data; 103 | artifact.seekg(0, std::ios::end); 104 | data.resize(artifact.tellg()); 105 | artifact.seekg(0, std::ios::beg); 106 | artifact.read(&data[0], data.size()); 107 | 108 | 109 | auto ptr = reinterpret_cast(data.data()); 110 | LLVMFuzzerTestOneInput(ptr, data.size()); 111 | return EXIT_SUCCESS; 112 | } 113 | 114 | #endif /* FUZZ_MAIN */ 115 | 116 | -------------------------------------------------------------------------------- /src/yystype.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id$ 25 | * 26 | * DESCRIPTION 27 | * Teng syntax symbols. 28 | * 29 | * AUTHORS 30 | * Filip Volejnik 31 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2003-09-17 (vasek) 34 | * Created. 35 | */ 36 | 37 | 38 | #include "util.h" 39 | #include "logging.h" 40 | #include "teng/writer.h" 41 | 42 | #include 43 | 44 | namespace Teng { 45 | 46 | StringWriter_t::StringWriter_t(std::string &str) 47 | : str(str) 48 | {} 49 | 50 | int StringWriter_t::write(const std::string &str) { 51 | this->str.append(str); 52 | return 0; 53 | } 54 | 55 | int StringWriter_t::write(const char *str) { 56 | this->str.append(str); 57 | return 0; 58 | } 59 | 60 | int StringWriter_t::write(const char *str, std::size_t size) { 61 | this->str.append(str, size); 62 | return 0; 63 | } 64 | 65 | int StringWriter_t::write(const std::string &, StringSpan_t interval) { 66 | this->str.append(interval.first, interval.second); 67 | return 0; 68 | } 69 | 70 | FileWriter_t::FileWriter_t(const std::string &filename) 71 | : file(fopen(filename.c_str(), "w")), borrowed(false) 72 | { 73 | if (!file && err) { 74 | logFatal( 75 | *err, 76 | "Cannot open file '" + filename + "' (" + strerr(errno) + ")" 77 | ); 78 | } 79 | } 80 | 81 | FileWriter_t::FileWriter_t(FILE *file) 82 | : Writer_t(), file(file), borrowed(true) 83 | { 84 | if (!file && err) 85 | logFatal(*err, "Got invalid file handle (nullptr)"); 86 | } 87 | 88 | FileWriter_t::~FileWriter_t() { 89 | if (!borrowed && file) 90 | fclose(file); 91 | } 92 | 93 | int FileWriter_t::write(const std::string &str) { 94 | if (!file) return -1; 95 | fwrite(str.data(), 1, str.length(), file); 96 | if (feof(file) || ferror(file)) { 97 | logFatal(*err, "Error writing to output (" + strerr(errno) + ")"); 98 | return -1; 99 | } 100 | return 0; 101 | } 102 | 103 | int FileWriter_t::write(const char *str) { 104 | return write(str, strlen(str)); 105 | } 106 | 107 | int FileWriter_t::write(const char *str, std::size_t size) { 108 | if (!file) return -1; 109 | fwrite(str, 1, size, file); 110 | if (feof(file) || ferror(file)) { 111 | logFatal(*err, "Error writing to output (" + strerr(errno) + ")"); 112 | return -1; 113 | } 114 | return 0; 115 | } 116 | 117 | int FileWriter_t::write(const std::string &str, StringSpan_t interval) { 118 | const char *cstr = str.data() + std::distance(str.begin(), interval.first); 119 | size_t len = std::distance(interval.first, interval.second); 120 | fwrite(cstr, 1, len, file); 121 | if (feof(file) || ferror(file)) { 122 | logFatal(*err, "Error writing to output (" + strerr(errno) + ")"); 123 | return -1; 124 | } 125 | return 0; 126 | } 127 | 128 | int FileWriter_t::flush() { 129 | if (!file) return -1; 130 | return (fflush(file) ? -1 : 0); 131 | } 132 | 133 | } // namespace Teng 134 | 135 | -------------------------------------------------------------------------------- /src/formatter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengformatter.h,v 1.2 2004-12-30 12:42:01 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng formater (a writer adapter). 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-25 (vasek) 34 | * Created. 35 | */ 36 | 37 | 38 | #ifndef TENGFORMATTER_H 39 | #define TENGFORMATTER_H 40 | 41 | #include 42 | #include 43 | #include 44 | 45 | #include "teng/error.h" 46 | #include "teng/stringview.h" 47 | #include "teng/writer.h" 48 | 49 | namespace Teng { 50 | 51 | /** @short Filter for formatting whitespaces in data. 52 | */ 53 | class Formatter_t { 54 | public: 55 | /** @short Mode of filtering whitespaces. 56 | */ 57 | enum Mode_t { 58 | MODE_COPY_PREV = -2, //!< used when format is unrecognized 59 | MODE_INVALID = -1, //!< invalid mode 60 | MODE_PASSWHITE = 0, //!< passes whitespaces verbatim 61 | MODE_NOWHITE, //!< discards all whitespaces 62 | MODE_ONESPACE, //!< truncate run of whitespaces to one space 63 | MODE_STRIPLINES, //!< remove leading and trailing spaces from line 64 | MODE_JOINLINES, //!< join lines into one long line 65 | MODE_NOWHITELINES, //!< remove empty and whitespace only lines 66 | }; 67 | 68 | /** @short Create new formatter. 69 | * @param writer output writer 70 | * @param initialMode initial mode of formatting 71 | */ 72 | Formatter_t(Writer_t &writer, Mode_t initialMode = MODE_PASSWHITE); 73 | 74 | /** @short Write string to output. 75 | * @param str string to be written 76 | * @return 0 OK, !0 error 77 | */ 78 | int write(string_view_t str); 79 | 80 | /** @short Flushes buffered data. 81 | * @return 0 OK, !0 error 82 | */ 83 | int flush(); 84 | 85 | /** @short Pushes new formatting mode to the stack. 86 | * @param mode new formatting mode 87 | * @return 0 OK, !0 error 88 | */ 89 | int push(Mode_t mode); 90 | 91 | /** @short Pops formatting mode from stack. 92 | * Ressambles state before pop. 93 | * @return old formatting mode 94 | */ 95 | Mode_t pop(); 96 | 97 | /** @short Returns formatting mode on top of the stack. 98 | * @return old formatting mode 99 | */ 100 | Mode_t top() {return modeStack.empty()? MODE_PASSWHITE: modeStack.top();} 101 | 102 | private: 103 | // don't copy 104 | Formatter_t(const Formatter_t &) = delete; 105 | Formatter_t &operator=(const Formatter_t &) = delete; 106 | 107 | /** @short Output writer. 108 | */ 109 | Writer_t &writer; 110 | 111 | /** @short Stack of formatting modes. 112 | */ 113 | std::stack modeStack; 114 | 115 | /** @short Buffer of whitespaces from previous run. 116 | */ 117 | std::string buffer; 118 | }; 119 | 120 | /** Returns format enum from format name. 121 | */ 122 | Formatter_t::Mode_t resolveFormat(const string_view_t &name); 123 | 124 | } // namespace Teng 125 | 126 | #endif // TENGFORMATTER_H 127 | 128 | -------------------------------------------------------------------------------- /tests/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: $ 25 | * 26 | * DESCRIPTION 27 | * Teng engine -- old tests 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-07 (burlog) 34 | * Coverted to catch2. 35 | */ 36 | 37 | #include 38 | 39 | #include "catch2/catch_approx.hpp" 40 | 41 | #ifndef SRC_DIR 42 | #define SRC_DIR "." 43 | #endif /* SRC_DIR */ 44 | 45 | #define TEST_ROOT SRC_DIR "/tests/" 46 | 47 | using Catch::Approx; 48 | 49 | inline std::string g( 50 | const std::string &templ, 51 | const Teng::Fragment_t &data = {}, 52 | const std::string &ct = "text/html", 53 | const std::string &encoding = "utf-8" 54 | ) { 55 | std::string result; 56 | Teng::StringWriter_t writer(result); 57 | Teng::Error_t err; 58 | Teng::Teng_t teng(TEST_ROOT); 59 | Teng::Teng_t::GenPageArgs_t args; 60 | args.contentType = ct; 61 | args.encoding = encoding; 62 | args.templateString = templ; 63 | teng.generatePage(args, data, writer, err); 64 | return result; 65 | } 66 | 67 | inline std::string g( 68 | Teng::Error_t &err, 69 | const std::string &templ, 70 | const Teng::Fragment_t &data = {}, 71 | const std::string ¶ms = "teng.conf", 72 | const std::string &lang = "", 73 | const std::string &ct = "text/html", 74 | const std::string &encoding = "utf-8" 75 | ) { 76 | std::string result; 77 | Teng::StringWriter_t writer(result); 78 | Teng::Teng_t teng(TEST_ROOT); 79 | Teng::Teng_t::GenPageArgs_t args; 80 | args.contentType = ct; 81 | args.encoding = encoding; 82 | args.templateString = templ; 83 | args.paramsFilename = TEST_ROOT + params; 84 | args.lang = lang; 85 | args.dictFilename = TEST_ROOT "dict.txt"; 86 | teng.generatePage(args, data, writer, err); 87 | return result; 88 | } 89 | 90 | inline std::string gFromFile( 91 | Teng::Error_t &err, 92 | const std::string &filename, 93 | const Teng::Fragment_t &data = {}, 94 | const std::string ¶ms = "teng.conf", 95 | const std::string &lang = "", 96 | const std::string &ct = "text/html", 97 | const std::string &encoding = "utf-8" 98 | ) { 99 | std::string result; 100 | Teng::StringWriter_t writer(result); 101 | Teng::Teng_t teng(TEST_ROOT); 102 | Teng::Teng_t::GenPageArgs_t args; 103 | args.contentType = ct; 104 | args.encoding = encoding; 105 | args.templateFilename = filename; 106 | args.paramsFilename = TEST_ROOT + params; 107 | args.lang = lang; 108 | args.dictFilename = TEST_ROOT "dict.txt"; 109 | teng.generatePage(args, data, writer, err); 110 | return result; 111 | } 112 | 113 | #define ERRLOG_TEST(LHS, RHS) \ 114 | for (uint64_t i = 0; i < std::min(LHS.size(), RHS.size()); ++i) { \ 115 | INFO("i=" + std::to_string(i)); \ 116 | REQUIRE(LHS[i] == RHS[i]); \ 117 | } \ 118 | REQUIRE(LHS.size() == RHS.size()) \ 119 | 120 | -------------------------------------------------------------------------------- /src/configuration.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengconfiguration.h,v 1.4 2010-06-11 07:46:26 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng configuration dictionary. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * Michal Bukovsky 32 | * 33 | * HISTORY 34 | * 2004-09-18 (vasek) 35 | * Created. 36 | */ 37 | 38 | #ifndef TENGCONFIGURATION_H 39 | #define TENGCONFIGURATION_H 40 | 41 | #include 42 | #include 43 | 44 | #include "dictionary.h" 45 | 46 | namespace Teng { 47 | 48 | /** The result type of isEnabled query. 49 | */ 50 | enum class teng_feature {unknown = 0, enabled = 1, disabled = 2}; 51 | 52 | /** 53 | * @short Language independed dictionary and configuration placeholder. 54 | */ 55 | class Configuration_t: public Dictionary_t { 56 | public: 57 | /** 58 | * @short Creates configuration object. 59 | * 60 | * @param root path of root for locating files 61 | */ 62 | Configuration_t(Error_t &err, std::shared_ptr filesystem); 63 | 64 | // @{ shortcuts to query configuration 65 | bool isDebugEnabled() const {return debug;} 66 | bool isErrorFragmentEnabled() const {return errorFragment;} 67 | bool isLogToOutputEnabled() const {return logToOutput;} 68 | bool isBytecodeEnabled() const {return bytecode;} 69 | bool isWatchFilesEnabled() const {return watchFiles;} 70 | uint32_t getMaxIncludeDepth() const {return maxIncludeDepth;} 71 | uint16_t getMaxDebugValLength() const {return maxDebugValLength;} 72 | bool isFormatEnabled() const {return format;} 73 | bool isAlwaysEscapeEnabled() const {return alwaysEscape;} 74 | bool isPrintEscapeEnabled() const {return printEscape;} 75 | bool isShortTagEnabled() const {return shortTag;} 76 | // @} 77 | 78 | /** Sets enabled to true if feature is enabled. 79 | */ 80 | teng_feature isEnabled(const string_view_t &name) const; 81 | 82 | /** Dumps configuration to stream. 83 | */ 84 | friend std::ostream &operator<<(std::ostream &o, const Configuration_t &c); 85 | 86 | protected: 87 | /** Called wheb new directive parsed. 88 | */ 89 | error_code 90 | new_directive( 91 | const char *name_ptr, std::size_t name_len, 92 | const char *value_ptr, std::size_t value_len 93 | ) override; 94 | 95 | bool debug; //!< the enabled (false) 96 | bool errorFragment; //!< the enabled (false) 97 | bool logToOutput; //!< log error goes to output (false) 98 | bool bytecode; //!< the enabled (false) 99 | bool watchFiles; //!< cached templates are checked for change (true) 100 | bool alwaysEscape; //!< always escape regardless on next instr (true) 101 | bool shortTag; //!< short tags enabled (false) 102 | bool format; //!< the enabled (true) 103 | uint32_t maxIncludeDepth; //!< maximal template include depth 104 | uint16_t maxDebugValLength; //!< maximal length of variable value length 105 | bool printEscape; //!< use escaping only if values are printed 106 | }; 107 | 108 | } // namespace Teng 109 | 110 | #endif // TENGCONFIGURATION_H 111 | 112 | -------------------------------------------------------------------------------- /src/fragment.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengstructs.cc,v 1.4 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng data types -- implementation. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-30 (vasek) 34 | * Created. 35 | * 2005-06-21 (roman) 36 | * Win32 support. 37 | */ 38 | 39 | #include "jsonutils.h" 40 | #include "teng/fragmentvalue.h" 41 | #include "teng/fragmentlist.h" 42 | #include "teng/fragment.h" 43 | 44 | namespace Teng { 45 | namespace { 46 | 47 | template 48 | void replace_item(where_t &&items, const std::string &name, type_t &&value) { 49 | auto iitem = items.find(name); 50 | if (iitem != items.end()) 51 | return iitem->second.setValue(std::forward(value)); 52 | items.emplace_hint(iitem, name, std::forward(value)); 53 | } 54 | 55 | } // namespace 56 | 57 | void Fragment_t::json(std::ostream &o) const { 58 | o << '{'; 59 | for (auto ivalue = begin(), evalue = end(); ivalue != evalue; ++ivalue) { 60 | if (ivalue != begin()) o << ", "; 61 | json::quote_string(o, ivalue->first); 62 | o << ": "; 63 | ivalue->second.json(o); 64 | } 65 | o << '}'; 66 | } 67 | 68 | void Fragment_t::dump(std::ostream &o) const { 69 | o << '{'; 70 | for (auto ivalue = begin(), evalue = end(); ivalue != evalue; ++ivalue) { 71 | if (ivalue != begin()) o << ", "; 72 | o << "'" << ivalue->first << "': "; 73 | ivalue->second.dump(o); 74 | } 75 | o << '}'; 76 | } 77 | 78 | void 79 | Fragment_t::addVariable(const std::string &name, const std::string &value) { 80 | replace_item(items, name, value); 81 | } 82 | 83 | void 84 | Fragment_t::addVariable(const std::string &name, std::string &&value) { 85 | replace_item(items, name, std::move(value)); 86 | } 87 | 88 | void Fragment_t::addIntVariable(const std::string &name, IntType_t value) { 89 | replace_item(items, name, value); 90 | } 91 | 92 | void Fragment_t::addRealVariable(const std::string &name, double value) { 93 | replace_item(items, name, value); 94 | } 95 | 96 | Fragment_t &Fragment_t::addFragment(const std::string &name) { 97 | return addFragmentList(name).addFragment(); 98 | } 99 | 100 | FragmentList_t & 101 | Fragment_t::addFragmentList(const std::string &name) { 102 | auto iitem = items.find(name); 103 | if (iitem != items.end()) 104 | return iitem->second.ensureFragmentList(); 105 | auto create_list = TypeTag_t(); 106 | return items.emplace_hint(iitem, name, create_list)->second.list_value; 107 | } 108 | 109 | void Fragment_t::addValue(const std::string &name, Fragment_t &&value) { 110 | addValue(name, FragmentValue_t(std::move(value))); 111 | } 112 | 113 | void Fragment_t::addValue(const std::string &name, FragmentList_t &&value) { 114 | addValue(name, FragmentValue_t(std::move(value))); 115 | } 116 | 117 | void Fragment_t::addValue(const std::string &name, FragmentValue_t &&value) { 118 | auto iitem = items.find(name); 119 | if (iitem != items.end()) 120 | iitem->second = std::move(value); 121 | else items.emplace_hint(iitem, name, std::move(value)); 122 | } 123 | 124 | } // namespace Teng 125 | 126 | -------------------------------------------------------------------------------- /src/functionutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengfunction.cc,v 1.18 2008-11-20 23:32:29 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng processor function (like len, substr, round or date) 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2003-09-26 (honza) 36 | * Created. 37 | * 2004-05-08 (vasek) 38 | * Polished code. 39 | * 2005-06-21 (roman) 40 | * Win32 support. 41 | * 2018-06-14 (burlog) 42 | * Moved from tengfunction.cc and polished. 43 | */ 44 | 45 | #ifndef TENGFUNCTIONUTIL_H 46 | #define TENGFUNCTIONUTIL_H 47 | 48 | #include 49 | #include 50 | 51 | #include "logging.h" 52 | #include "function.h" 53 | 54 | namespace Teng { 55 | namespace builtin { 56 | 57 | // shortcuts 58 | using Ctx_t = FunctionCtx_t; 59 | using Args_t = FunctionArgs_t; 60 | using Result_t = FunctionResult_t; 61 | 62 | /** Handy struct that caches converted numeric arguments to string. 63 | */ 64 | struct string_ptr_t { 65 | /** Printer for Value_t::print() that return pointer to given const 66 | * std::string & or pointer to cached string. 67 | */ 68 | struct cache_t { 69 | const std::string *operator()(const string_view_t &v) { 70 | tmp.assign(v.data(), v.size()); 71 | return &tmp; 72 | } 73 | const std::string *operator()(const std::string &str) { 74 | return &str; 75 | } 76 | std::string tmp; //!< storage of string repr of non string values 77 | }; 78 | 79 | /** C'tor. 80 | */ 81 | string_ptr_t(const Value_t &value) 82 | : arg(value.print(std::ref(cached_str))) 83 | {} 84 | 85 | // don't copy 86 | string_ptr_t(const string_ptr_t &) = delete; 87 | string_ptr_t &operator=(const string_ptr_t &) = delete; 88 | 89 | // ptr access 90 | const std::string *operator->() const {return arg;} 91 | const std::string &operator*() const {return *arg;} 92 | char operator[](std::string::size_type i) const {return (*arg)[i];} 93 | 94 | cache_t cached_str; //!< where are non string values cached 95 | const std::string *arg; //!< pointer to string value or to tmp 96 | }; 97 | 98 | /** Convenient function for reporting error. 99 | */ 100 | Result_t failed(Ctx_t &ctx, const char *fun, const std::string &msg) { 101 | logWarning(ctx.err, ctx.pos, std::string(fun) + "(): " + msg); 102 | return Result_t(); 103 | } 104 | 105 | /** Convenient function for reporting error. 106 | */ 107 | Result_t wrongNumberOfArgs(Ctx_t &ctx, const char *fun, int exp) { 108 | return failed( 109 | ctx, 110 | fun, 111 | "the function expects exactly " + std::to_string(exp) + " arg(s)" 112 | ); 113 | } 114 | 115 | /** Convenient function for reporting error. 116 | */ 117 | Result_t wrongNumberOfArgs(Ctx_t &ctx, const char *fun, int f, int t) { 118 | return failed( 119 | ctx, 120 | fun, 121 | "the function expects from " + std::to_string(f) 122 | + " to " + std::to_string(t) + " args" 123 | ); 124 | } 125 | 126 | /** Convenient function for reporting error. 127 | */ 128 | Result_t atLeastXArg(Ctx_t &ctx, const char *fun, int x) { 129 | return failed( 130 | ctx, 131 | fun, 132 | "the function expects at least " + std::to_string(x) + " arg(s)" 133 | ); 134 | } 135 | 136 | } // namespace builtin 137 | } // namespace Teng 138 | 139 | #endif /* TENGFUNCTIONUTIL_H */ 140 | 141 | -------------------------------------------------------------------------------- /src/semanticquery.cc: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #include "debug.h" 40 | #include "syntax.hh" 41 | #include "logging.h" 42 | #include "instruction.h" 43 | #include "semanticexpr.h" 44 | #include "semanticvar.h" 45 | #include "semanticquery.h" 46 | 47 | namespace Teng { 48 | namespace Parser { 49 | 50 | void generate_query(Context_t *ctx, const Variable_t &var, bool warn) { 51 | generate(ctx, var.pos); 52 | note_optimization_point(ctx, true); 53 | generate_var(ctx, var, false); 54 | 55 | // warn if query is name($some.var) 56 | if (warn) { 57 | logWarning( 58 | ctx, 59 | var.pos, 60 | "In query expression the identifier shouldn't be denoted by $ sign" 61 | ); 62 | } 63 | } 64 | 65 | /** Generates instructions implementing query expression. 66 | * If arity is not 1 then query is badly formated and instruction is not 67 | * generated. 68 | */ 69 | template 70 | NAryExpr_t query_expr(Context_t *ctx, const Token_t &token, uint32_t arity) { 71 | if (std::is_same::value) { 72 | logWarning( 73 | ctx, 74 | token.pos, 75 | "The defined() query is deprecated; " 76 | "use isempty() or exists() instead" 77 | ); 78 | } else if (std::is_same::value) { 79 | logWarning( 80 | ctx, 81 | token.pos, 82 | "The count() query is deprecated; " 83 | "use _count builtin variable instead" 84 | ); 85 | } 86 | if (arity == 1) { 87 | generate(ctx, token.pos); 88 | } else { 89 | logError( 90 | ctx, 91 | token.pos, 92 | "Invalid variable identifier in " + token.view() + "()" 93 | ); 94 | generate_val(ctx, token.pos, Value_t()); 95 | } 96 | return NAryExpr_t(token, arity); 97 | } 98 | 99 | // instatiations 100 | template 101 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 102 | template 103 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 104 | template 105 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 106 | template 107 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 108 | template 109 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 110 | 111 | template 112 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 113 | template 114 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 115 | template 116 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 117 | template 118 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 119 | template 120 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 121 | template 122 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 123 | template 124 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 125 | template 126 | NAryExpr_t query_expr(Context_t *, const Token_t &, uint32_t); 127 | 128 | } // namespace Parser 129 | } // namespace Teng 130 | 131 | -------------------------------------------------------------------------------- /src/function.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengfunction.cc,v 1.18 2008-11-20 23:32:29 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng processor function (like len, substr, round or date) 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2003-09-26 (honza) 36 | * Created. 37 | * 2004-05-08 (vasek) 38 | * Polished code. 39 | * 2005-06-21 (roman) 40 | * Win32 support. 41 | * 2018-06-14 (burlog) 42 | * Polished. 43 | */ 44 | 45 | #include 46 | 47 | #include "hex.h" 48 | #include "utf8.h" 49 | #include "platform.h" 50 | #include "functionutil.h" 51 | #include "functionstring.h" 52 | #include "functionnumber.h" 53 | #include "functionescaping.h" 54 | #include "functionother.h" 55 | #include "functiondate.h" 56 | #include "function.h" 57 | 58 | namespace Teng { 59 | namespace { 60 | 61 | struct FunctionStub_t { 62 | const char *name; // teng name 63 | Function_t func; // C++ function addr 64 | }; 65 | 66 | FunctionStub_t builtin_functions[] = { 67 | // number 68 | {"int", builtin::toint}, // like (int) in C 69 | {"isnumber", builtin::isnumber}, // true if arg is number 70 | {"random", builtin::random}, // random integer 71 | {"round", builtin::round}, // round(number, precision) 72 | {"numformat", builtin::numformat}, // format number for display 73 | 74 | // string 75 | {"len", builtin::len}, // like strlen in C 76 | {"strtolower", builtin::strtolower}, // utf-8 lowercase 77 | {"strtoupper", builtin::strtoupper}, // utf-8 uppercase 78 | {"substr", builtin::substr}, // like str[a:b] in Python 79 | {"wordsubstr", builtin::wordsubstr}, // substr preserving words 80 | {"reorder", builtin::reorder}, // like sprintf with %s 81 | {"nl2br", builtin::nl2br}, // convert '\n' =>
82 | {"replace", builtin::replace}, // string replace 83 | {"regex_replace", builtin::regex_replace}, // regex replace 84 | 85 | // escaping 86 | {"escape", builtin::escape}, // for example "<" => "<" 87 | {"unescape", builtin::unescape}, // for example "<" => "<" 88 | {"urlescape", builtin::urlescape}, // escape strange chars in urls 89 | {"urlunescape", builtin::urlunescape}, // unescape url encoding 90 | {"quoteescape", builtin::quoteescape}, // escape strange chars 91 | {"jsonify", builtin::jsonify}, // convert and escape to json 92 | 93 | // date 94 | {"date", builtin::date}, // like strftime 95 | {"now", builtin::now}, // like gettimeofday 96 | {"sectotime", builtin::sectotime}, // convert seconds to HH:MM:SS 97 | {"timestamp", builtin::timestamp}, // returns current timestamp 98 | 99 | // other 100 | {"isenabled", builtin::isenabled}, // isenabled(feature) 101 | {"dictexist", builtin::dictexist}, // dictexist(key) 102 | {"getdict", builtin::getdict}, // getdict(key, default) 103 | 104 | // sentinel 105 | {nullptr, nullptr} // end of list 106 | }; 107 | 108 | } // namespace 109 | 110 | Invoker_t 111 | findFunction(const std::string &name) { 112 | for (auto *p = builtin_functions; p->name; ++p) 113 | if (p->name == name) 114 | return {name, p->func}; 115 | return {name, nullptr}; 116 | } 117 | 118 | } // namespace Teng 119 | 120 | -------------------------------------------------------------------------------- /src/util.cc: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengutil.cc,v 1.5 2010-06-11 08:25:35 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng utilities. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * 32 | * HISTORY 33 | * 2003-09-24 (vasek) 34 | * Created. 35 | * 2005-06-21 (roman) 36 | * Win32 support. 37 | * 38 | */ 39 | 40 | #include 41 | #include 42 | #include 43 | 44 | #include "platform.h" 45 | #include "util.h" 46 | 47 | namespace Teng { 48 | 49 | void normalizeFilename(std::string &filename) { 50 | // check for empty filename 51 | if (filename.empty()) return; 52 | 53 | CONVERTNAMEBYPLATFORM(filename) 54 | 55 | // cache of filename parts 56 | std::vector parts; 57 | parts.reserve(10); 58 | // run through filename and split it by slashes 59 | for (std::string::size_type slash = 0; ; ) { 60 | // find slash 61 | std::string::size_type nextSlash = filename.find('/', slash); 62 | // cut filename part 63 | std::string part = filename.substr(slash, nextSlash - slash); 64 | // if part is non-empty ("" or ".") 65 | if (!part.empty() && (part != ".")) { 66 | // if part means 'parent dir' 67 | if (part == "..") { 68 | // if not at root => remove previous part 69 | if (!parts.empty()) 70 | parts.pop_back(); 71 | } else { 72 | // push part into cache 73 | parts.push_back(part); 74 | } 75 | } 76 | // do until end-of-string 77 | if (nextSlash == std::string::npos) break; 78 | // move after slash 79 | slash = nextSlash + 1; 80 | } 81 | 82 | // erase current filename 83 | filename.erase(); 84 | // run through part cache and glue them with '/' together 85 | for (auto &part: parts) { 86 | #ifdef WIN32 87 | if (!filename.empty()) 88 | #endif //WIN32 89 | filename.push_back('/'); 90 | filename.append(part); 91 | } 92 | } 93 | 94 | std::string clip(std::string str, unsigned int len) { 95 | static const unsigned int CLIP_DOTS_COUNT = 3; 96 | if (str.size() <= len) return str; 97 | 98 | // len is even shorter than CLIP_DOTS_COUNT 99 | if (len <= CLIP_DOTS_COUNT) { 100 | str.resize(0); 101 | for (auto i = 0u; i < len; ++i) 102 | str.push_back('.'); 103 | return str; 104 | } 105 | 106 | // str.size() > len && len > CLIP_DOTS_COUNT 107 | // index to the first character over the limit 108 | auto i = len - CLIP_DOTS_COUNT; 109 | switch (str[i] & 0b11000000) { 110 | case 0b00000000: // ascii char 111 | case 0b01000000: // ascii char 112 | str.resize(i); 113 | break; 114 | case 0b10000000: // utf-8 continuation char 115 | do { 116 | if ((str[--i] & 0b11000000) != 0b10000000) 117 | break; 118 | } while (i > 0); 119 | str.resize(i); 120 | break; 121 | case 0b11000000: // utf-8 leading char 122 | str.resize(i - 1); 123 | break; 124 | } 125 | 126 | // append three dots 127 | for (auto i = 0u; i < CLIP_DOTS_COUNT; ++i) 128 | str.push_back('.'); 129 | return str; 130 | } 131 | 132 | std::string tolower(std::string str) { 133 | std::transform(str.begin(), str.end(), str.begin(), ::tolower); 134 | return str; 135 | } 136 | 137 | std::string strerr(int errno_value) { 138 | char system_error[1024]; 139 | system_error[0] = '\0'; 140 | return strerror_r(errno_value, system_error, sizeof(system_error)); 141 | } 142 | 143 | } // namespace Teng 144 | 145 | -------------------------------------------------------------------------------- /src/functionother.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengfunction.cc,v 1.18 2008-11-20 23:32:29 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng processor function (like len, substr, round or date) 28 | * 29 | * AUTHORS 30 | * Jan Nemec 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2003-09-26 (honza) 36 | * Created. 37 | * 2004-05-08 (vasek) 38 | * Polished code. 39 | * 2005-06-21 (roman) 40 | * Win32 support. 41 | * 2018-06-14 (burlog) 42 | * Polished. 43 | */ 44 | 45 | #ifndef TENGFUNCTIONOTHER_H 46 | #define TENGFUNCTIONOTHER_H 47 | 48 | #include 49 | 50 | #include "platform.h" 51 | #include "configuration.h" 52 | #include "functionutil.h" 53 | #include "function.h" 54 | 55 | namespace Teng { 56 | namespace builtin { 57 | 58 | /** Check whether given feature is enabled. 59 | * 60 | * @param args Function arguments (list of values). 61 | * @param ctx Teng function ctx. 62 | * @param result Function's result value. 63 | */ 64 | Result_t isenabled(Ctx_t &ctx, const Args_t &args) { 65 | if (args.size() != 1) 66 | return wrongNumberOfArgs(ctx, "isenabled", 1); 67 | 68 | auto &arg = args.back(); 69 | if (!arg.is_string_like()) 70 | return failed(ctx, "isenabled", "Arg must be a string"); 71 | auto feature = arg.string(); 72 | 73 | // ensure runtime context 74 | ctx.runtime_ctx_needed(); 75 | 76 | switch (ctx.params.isEnabled(feature)) { 77 | case teng_feature::disabled: 78 | return Result_t(false); 79 | case teng_feature::enabled: 80 | return Result_t(true); 81 | case teng_feature::unknown: 82 | return failed(ctx, "isenabled", "Unknown feature '" + feature + "'"); 83 | } 84 | throw std::runtime_error(__PRETTY_FUNCTION__); 85 | } 86 | 87 | /** Check whether given key is present in dictionaries. 88 | * 89 | * @param args Function arguments (list of values). 90 | * @param ctx Teng function ctx. 91 | * @param result Function's result value. 92 | */ 93 | Result_t dictexist(Ctx_t &ctx, const Args_t &args) { 94 | if (args.size() != 1) 95 | return wrongNumberOfArgs(ctx, "dictexist", 1); 96 | 97 | auto &arg = args.back(); 98 | if (!arg.is_string_like()) 99 | return failed(ctx, "dictexist", "Arg must be a string"); 100 | auto key = arg.string(); 101 | 102 | return Result_t(ctx.dict.lookup(key) || ctx.params.lookup(key)); 103 | } 104 | 105 | /** Returns value for desired key from dictionaries. 106 | * 107 | * @param args Function arguments (list of values). 108 | * @param ctx Teng function ctx. 109 | * @param result Function's result value. 110 | */ 111 | Result_t getdict(Ctx_t &ctx, const Args_t &args) { 112 | if ((args.size() < 1) || (args.size() > 2)) 113 | return wrongNumberOfArgs(ctx, "getdict", 1, 2); 114 | 115 | auto &arg0 = *args.rbegin(); 116 | if (!arg0.is_string_like()) 117 | return failed(ctx, "getdict", "First arg must be a string"); 118 | auto key = arg0.string(); 119 | 120 | // set result value 121 | if (auto *val = ctx.dict.lookup(key)) 122 | return Result_t(*val); 123 | if (auto *val = ctx.params.lookup(key)) 124 | return Result_t(*val); 125 | 126 | // no default given 127 | if (args.size() == 1) 128 | return Result_t(); 129 | 130 | // read default value 131 | auto &arg1 = *++args.rbegin(); 132 | if (!arg1.is_string_like()) 133 | return failed(ctx, "getdict", "Second arg must be a string"); 134 | auto def = arg1.string(); 135 | return Result_t(def); 136 | } 137 | 138 | } // namespace builtin 139 | } // namespace Teng 140 | 141 | #endif /* TENGFUNCTIONOTHER_H */ 142 | 143 | -------------------------------------------------------------------------------- /src/semanticcase.cc: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #include "debug.h" 40 | #include "program.h" 41 | #include "logging.h" 42 | #include "parserdiag.h" 43 | #include "instruction.h" 44 | #include "parsercontext.h" 45 | #include "semanticcase.h" 46 | 47 | namespace Teng { 48 | namespace Parser { 49 | 50 | void prepare_case(Context_t *ctx) { 51 | expr_diag_sentinel(ctx, diag_code::case_cond); 52 | ctx->case_option_addrs.push(); 53 | } 54 | 55 | void prepare_case_cond(Context_t *ctx, const Token_t &token) { 56 | expr_diag(ctx, diag_code::case_option); 57 | generate(ctx, token.pos); 58 | } 59 | 60 | uint32_t generate_case_cmp(Context_t *ctx, Literal_t &literal) { 61 | // warn if there is more than one branch valid for same value 62 | for (auto addr: ctx->case_option_addrs.top()) { 63 | auto &instr = (*ctx->program)[addr].as(); 64 | if (instr.value == literal.value) { 65 | auto val = literal.value.string(); 66 | logWarning(ctx, instr.pos(), "Duplicit case operand: " + val); 67 | logWarning(ctx, literal.pos, "Next seen here"); 68 | break; 69 | } 70 | } 71 | 72 | // generate instructions 73 | generate(ctx, 0, literal.pos); 74 | ctx->case_option_addrs.top().push(ctx->program->size()); 75 | generate(ctx, std::move(literal.value), literal.pos); 76 | generate(ctx, literal.pos); 77 | return 0; 78 | } 79 | 80 | void update_case_jmp(Context_t *ctx, const Token_t &token, uint32_t alts) { 81 | expr_diag(ctx, diag_code::case_option_branch); 82 | for (; alts; --alts) { 83 | auto addr = ctx->curr_branch_addrs().pop(); 84 | auto &instr = (*ctx->program)[addr].as(); 85 | instr.addr_offset = ctx->program->size() - addr - 1; 86 | } 87 | ctx->curr_branch_addrs().push(ctx->program->size()); 88 | generate(ctx, token.pos); 89 | } 90 | 91 | uint32_t 92 | generate_case_next(Context_t *ctx, Literal_t &literal, uint32_t alts) { 93 | ctx->curr_branch_addrs().push(ctx->program->size()); 94 | generate(ctx, literal.pos); 95 | generate_case_cmp(ctx, literal); 96 | return alts + 1; 97 | } 98 | 99 | void finalize_case_branch(Context_t *ctx, const Token_t &token) { 100 | auto branch_case_addr = ctx->curr_branch_addrs().pop(); 101 | auto &instr = (*ctx->program)[branch_case_addr].as(); 102 | instr.addr_offset = ctx->program->size() - branch_case_addr; 103 | ctx->curr_branch_addrs().push(ctx->program->size()); 104 | generate(ctx, token.pos); 105 | } 106 | 107 | NAryExpr_t finalize_case(Context_t *ctx, const Token_t &token, uint32_t arity) { 108 | // update addr offsets of jmp instruction at the end of all branches 109 | for (auto tmp_arity = arity; --tmp_arity;) { 110 | auto branch_end_addr = ctx->curr_branch_addrs().pop(); 111 | auto &instr = (*ctx->program)[branch_end_addr].as(); 112 | instr.addr_offset = ctx->program->size() - branch_end_addr - 1; 113 | } 114 | 115 | // generate instruction that remove case value from prg stack 116 | generate(ctx, token.pos); 117 | 118 | // clear stored option addresses 119 | ctx->case_option_addrs.pop(); 120 | 121 | // clear case expr diagnostic code 122 | ctx->expr_diag.pop(); 123 | 124 | // done 125 | return NAryExpr_t(token, arity + 1, true); 126 | } 127 | 128 | } // namespace Parser 129 | } // namespace Teng 130 | 131 | -------------------------------------------------------------------------------- /src/semanticother.cc: -------------------------------------------------------------------------------- 1 | /* !don't remove! -*- C++ -*- 2 | * 3 | * Teng -- a general purpose templating engine. 4 | * Copyright (C) 2004 Seznam.cz, a.s. 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | * Seznam.cz, a.s. 21 | * Naskove 1, Praha 5, 15000, Czech Republic 22 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 23 | * 24 | * 25 | * $Id: tengsyntax.yy,v 1.14 2010-06-11 08:25:35 burlog Exp $ 26 | * 27 | * DESCRIPTION 28 | * Teng grammar semantic actions. 29 | * 30 | * AUTHORS 31 | * Stepan Skrob 32 | * Michal Bukovsky 33 | * 34 | * HISTORY 35 | * 2018-06-07 (burlog) 36 | * Moved from syntax.yy. 37 | */ 38 | 39 | #include "debug.h" 40 | #include "yystype.h" 41 | #include "syntax.hh" 42 | #include "program.h" 43 | #include "logging.h" 44 | #include "instruction.h" 45 | #include "parsercontext.h" 46 | #include "configuration.h" 47 | #include "semanticother.h" 48 | 49 | namespace Teng { 50 | namespace Parser { 51 | 52 | void include_file(Context_t *ctx, const Pos_t &pos, const Options_t &opts) { 53 | // ensure that file option exists 54 | auto iopt = opts.find("file"); 55 | if (iopt == opts.end()) { 56 | logError(ctx, pos, "Can't include file; the 'file' option is missing"); 57 | return; 58 | } 59 | 60 | // ensure that we not go beyond include limit 61 | if (ctx->include_level() >= ctx->params->getMaxIncludeDepth()) { 62 | logError(ctx, pos, "Can't include file; include level is too deep"); 63 | return; 64 | } 65 | 66 | // compile file (append compiled file at the end of current program) 67 | ctx->load_file(iopt->value.string(), pos); 68 | } 69 | 70 | void ignore_include(Context_t *ctx, const Token_t &token, bool empty) { 71 | if (empty) { 72 | logError( 73 | ctx, 74 | token.pos, 75 | "Missing filename to include; ignoring the include directive" 76 | ); 77 | } else { 78 | switch (ctx->unexpected_token) { 79 | case LEX2_EOF: 80 | case LEX2::END: 81 | logError( 82 | ctx, 83 | token.pos, 84 | "Premature end of directive; " 85 | "ignoring the include directive" 86 | ); 87 | break; 88 | default: 89 | logError( 90 | ctx, 91 | token.pos, 92 | "Invalid or excessive tokens in ; " 93 | "ignoring the include directive" 94 | ); 95 | break; 96 | } 97 | reset_error(ctx); 98 | } 99 | } 100 | 101 | void ignore_unknown_directive(Context_t *ctx, const Token_t &token) { 102 | logError(ctx, token.pos, "Unknown Teng directive: " + token.view() + "?>"); 103 | reset_error(ctx); 104 | } 105 | 106 | void ignore_excessive_options(Context_t *ctx, const Pos_t &pos) { 107 | logWarning( 108 | ctx, 109 | pos, 110 | "This directive doesn't accept any options; ignoring them" 111 | ); 112 | } 113 | 114 | void new_option(Context_t *ctx, const Token_t &name, Literal_t &&literal) { 115 | ctx->opts_sym.emplace(name.view(), std::move(literal.value)); 116 | } 117 | 118 | uint32_t generate_func(Context_t *ctx, const Token_t &name, uint32_t nargs) { 119 | if (!ctx->params->isPrintEscapeEnabled()) { 120 | // be optimal for unescape($variable) 121 | // if last instr. is VAR and should be escaped 122 | // unescaping a single variable -- change escaping status of that var 123 | if ((nargs == 1) && (name.view() == "unescape")) { 124 | if (ctx->program->back().opcode() == OPCODE::VAR) { 125 | auto &instr = ctx->program->back().as(); 126 | if (instr.escape) { 127 | instr.escape = false; 128 | return nargs; 129 | } 130 | } 131 | } 132 | } 133 | 134 | // also include diagnostic message if there any 135 | ctx->expr_diag.pop(); 136 | ctx->expr_diag.unwind(ctx, ctx->unexpected_token); 137 | 138 | // regular function 139 | bool is_udf = name.token_id == LEX2::UDF_IDENT; 140 | generate(ctx, name.str(), nargs, name.pos, is_udf); 141 | return nargs; 142 | } 143 | 144 | } // namespace Parser 145 | } // namespace Teng 146 | 147 | -------------------------------------------------------------------------------- /src/flexhelpers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tenglex1.h,v 1.3 2006-10-18 08:31:09 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng helpers for FLEX. 28 | * 29 | * AUTHORS 30 | * Stepan Skrob 31 | * Michal Bukovsky 32 | * 33 | * HISTORY 34 | * 2003-09-18 (stepan) 35 | * Created. 36 | * 2018-07-07 (burlog) 37 | * Cleaned. 38 | */ 39 | 40 | #ifndef TENGHELPERSEX1_H 41 | #define TENGHELPERSEX1_H 42 | 43 | #include 44 | #include 45 | 46 | #include "teng/stringview.h" 47 | 48 | namespace Teng { 49 | namespace Parser { 50 | 51 | /** String values used for flex scanner requiring that buffers must ends 52 | * with flex end-of-buffer (two) zero bytes. 53 | */ 54 | struct flex_string_value_t: public string_value_t { 55 | /** C'tor: allocates new buffer finished by two zero bytes. 56 | */ 57 | explicit flex_string_value_t(std::size_t length) 58 | : string_value_t(new char[length + 2], length) 59 | {disposable_ptr[length] = disposable_ptr[length + 1 ] = '\0';} 60 | 61 | /** C'tor: allocates new buffer finished by two zero bytes. 62 | */ 63 | explicit flex_string_value_t(const std::string& data) 64 | : flex_string_value_t(data.size()) 65 | { 66 | std::copy(data.data(), data.data() + data.size(), disposable_ptr); 67 | } 68 | 69 | /** Returns really allocated size including end-of-buffer bytes. 70 | */ 71 | std::size_t flex_size() const {return size() + 2;} 72 | }; 73 | 74 | /** Mutable string view that guaranties availability of the two extra bytes 75 | * past the string view last byte for flex end-of-buffer zero bytes. 76 | */ 77 | struct flex_string_view_t: public mutable_string_view_t { 78 | /** C'tor: conversion. 79 | */ 80 | explicit flex_string_view_t(flex_string_value_t &value) 81 | : mutable_string_view_t(value.data(), value.size()), 82 | recover(true) 83 | { 84 | eob[0] = std::exchange(ptr[len + 0], '\0'); 85 | eob[1] = std::exchange(ptr[len + 1], '\0'); 86 | } 87 | 88 | /** C'tor: conversion. 89 | */ 90 | flex_string_view_t( 91 | flex_string_view_t &value, 92 | std::size_t offset, 93 | std::size_t limit 94 | ): mutable_string_view_t( 95 | value.data() + offset, 96 | value.data() + offset + limit 97 | ), recover(true) { 98 | eob[0] = std::exchange(ptr[len + 0], '\0'); 99 | eob[1] = std::exchange(ptr[len + 1], '\0'); 100 | } 101 | 102 | /** C'tor: move. 103 | */ 104 | flex_string_view_t(flex_string_view_t &&other) noexcept 105 | : mutable_string_view_t(std::move(other)), 106 | recover(other.recover), eob{other.eob[0], other.eob[1]} 107 | {other.recover = false;} 108 | 109 | /** Assigment: move. 110 | */ 111 | flex_string_view_t &operator=(flex_string_view_t &&other) noexcept { 112 | if (this != &other) { 113 | this->~flex_string_view_t(); 114 | new (this) flex_string_view_t(std::move(other)); 115 | } 116 | return *this; 117 | } 118 | 119 | /** D'tor. 120 | */ 121 | ~flex_string_view_t() noexcept {if (recover) reset();} 122 | 123 | /** Brings the string to the original state. 124 | */ 125 | void reset() { 126 | recover = false; 127 | ptr[len + 0] = eob[0]; 128 | ptr[len + 1] = eob[1]; 129 | } 130 | 131 | /** Returns saved eob characters. 132 | */ 133 | const char *saved_eob() const {return eob;} 134 | 135 | /** Returns really allocated size including end-of-buffer bytes. 136 | */ 137 | std::size_t flex_size() const {return size() + 2;} 138 | 139 | protected: 140 | // don't copy 141 | flex_string_view_t(const flex_string_view_t &) = delete; 142 | flex_string_view_t &operator=(const flex_string_view_t &) = delete; 143 | 144 | bool recover; //!< recover the last two bytes replaced with flex EOB 145 | char eob[2]; //!< two bytes that have been replaced by EOB 146 | }; 147 | 148 | } // namespace Parser 149 | } // namespace Teng 150 | 151 | #endif /* TENGFLEXHELPERS_H */ 152 | 153 | -------------------------------------------------------------------------------- /src/instructionpointer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengprocessor.cc,v 1.15 2010-06-11 07:46:26 burlog Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng processor. Instruction pointer. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-07-07 (burlog) 34 | * Cleated. 35 | */ 36 | 37 | #ifndef TENGINSTRUCTIONPOINTER_H 38 | #define TENGINSTRUCTIONPOINTER_H 39 | 40 | #include "instruction.h" 41 | #include "program.h" 42 | #include "processor.h" 43 | 44 | namespace Teng { 45 | 46 | /** Some, even whole, part of program. 47 | */ 48 | struct SubProgram_t { 49 | const Instruction_t &operator[](int64_t i) const {return program[i];} 50 | const int64_t start; //!< pointer to the first instruction in program 51 | const int64_t end; //!< pointer to one past last instruction in program 52 | const Program_t &program; //!< the whole program 53 | }; 54 | 55 | /** Represents safe instruction pointer. 56 | */ 57 | struct InstructionPointer_t { 58 | /** C'tor. 59 | */ 60 | InstructionPointer_t(const SubProgram_t &program) 61 | : value(program.start), program(program) 62 | {} 63 | 64 | /** Moves instruction pointer to given address. 65 | */ 66 | InstructionPointer_t &operator=(int64_t new_value) { 67 | if (new_value >= program.end) 68 | throw std::runtime_error("instruction pointer overflow"); 69 | if (new_value < program.start) 70 | throw std::runtime_error("instruction pointer underflow"); 71 | value = new_value; 72 | return *this; 73 | } 74 | 75 | /** Increments the instruction pointer (it check boundaries). 76 | */ 77 | int64_t operator++() { 78 | *this += 1; 79 | return value; 80 | } 81 | 82 | /** Increments the instruction pointer (it check boundaries). 83 | */ 84 | int64_t operator++(int) { 85 | int64_t tmp = value; 86 | *this += 1; 87 | return tmp; 88 | } 89 | 90 | /** Decrements the instruction pointer (it check boundaries). 91 | */ 92 | int64_t operator--() { 93 | *this -= 1; 94 | return value; 95 | } 96 | 97 | /** Decrements the instruction pointer (it check boundaries). 98 | */ 99 | int64_t operator--(int) { 100 | int64_t tmp = value; 101 | *this -= 1; 102 | return tmp; 103 | } 104 | 105 | /** Increments the instruction pointer (it check boundaries). 106 | */ 107 | int64_t operator+=(int64_t incr) { 108 | if (incr == -1) 109 | throw std::runtime_error("never ending loop detected"); 110 | return value = *this + incr; 111 | } 112 | 113 | /** Decrements the instruction pointer (it check boundaries). 114 | */ 115 | int64_t operator-=(int64_t incr) { 116 | if (incr == 1) 117 | throw std::runtime_error("never ending loop detected"); 118 | return value = *this - incr; 119 | } 120 | 121 | /** Increments the instruction pointer (it check boundaries). 122 | */ 123 | int64_t operator+(int64_t incr) const { 124 | auto new_value = value + incr; 125 | if (new_value > program.end) 126 | throw std::runtime_error("instruction pointer overflow"); 127 | return new_value; 128 | } 129 | 130 | /** Increments the instruction pointer (it check boundaries). 131 | */ 132 | int64_t operator-(int64_t incr) const { 133 | auto new_value = value - incr; 134 | if (new_value < program.start) 135 | throw std::runtime_error("instruction pointer underflow"); 136 | return new_value; 137 | } 138 | 139 | /** Returns true if value of ip is less than given address. 140 | */ 141 | int64_t operator<(int64_t addr) const { 142 | return value < addr; 143 | } 144 | 145 | /** Returns numeric value of instruction pointer. 146 | */ 147 | int64_t operator*() const {return value;} 148 | 149 | protected: 150 | int64_t value; //!< never will be changed to unsigned !! 151 | const SubProgram_t &program; //!< evaluated program 152 | }; 153 | 154 | } // namespace Teng 155 | 156 | #endif /* TENGINSTRUCTIONPOINTER_H */ 157 | 158 | -------------------------------------------------------------------------------- /include/teng/counted_ptr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengvalue.h,v 1.3 2007-05-21 15:43:28 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng variables type. 28 | * 29 | * AUTHORS 30 | * Michal Bukovsky 31 | * 32 | * HISTORY 33 | * 2018-06-07 (burlog) 34 | * reference counting ptr 35 | */ 36 | 37 | #include 38 | 39 | #ifndef TENGCOUNTED_PTR_H 40 | #define TENGCOUNTED_PTR_H 41 | 42 | namespace Teng { 43 | 44 | /** It's similar to shared_ptr but does not provide any thread safety and can 45 | * release the held pointer. 46 | */ 47 | template 48 | class counted_ptr { 49 | public: 50 | /** C'tor: default. 51 | */ 52 | counted_ptr() noexcept 53 | : ptr(nullptr), refs(nullptr) 54 | {} 55 | 56 | /** C'tor: copy. 57 | */ 58 | counted_ptr(const counted_ptr &other) noexcept 59 | : ptr(other.ptr), refs(other.refs) 60 | {++*refs;} 61 | 62 | /** C'tor: move. 63 | */ 64 | counted_ptr(counted_ptr &&other) noexcept 65 | : ptr(std::exchange(other.ptr, nullptr)), 66 | refs(std::exchange(other.refs, nullptr)) 67 | {} 68 | 69 | /** Assigment: copy. 70 | */ 71 | counted_ptr &operator=(const counted_ptr &other) noexcept { 72 | if (this != &other) { 73 | reset(); 74 | new (this) counted_ptr(other); 75 | } 76 | return *this; 77 | } 78 | 79 | /** Assigment: move. 80 | */ 81 | counted_ptr &operator=(counted_ptr &&other) noexcept { 82 | if (this != &other) { 83 | reset(); 84 | new (this) counted_ptr(std::move(other)); 85 | } 86 | return *this; 87 | } 88 | 89 | /** D'tor. 90 | */ 91 | ~counted_ptr() noexcept {reset();} 92 | 93 | /** Dispose the pointer. 94 | */ 95 | void reset() noexcept { 96 | if (refs && (--*refs == 0)) { 97 | ptr->~type_t(); // this turn off asan warn 98 | delete [] reinterpret_cast(ptr); 99 | } 100 | } 101 | 102 | /** Returns pointer to held object. 103 | */ 104 | type_t *operator->() const {return ptr;} 105 | 106 | /** Returns reference to held object. 107 | */ 108 | type_t &operator*() const {return *ptr;} 109 | 110 | /** Returns true if caller is exclusive owner of the resource. 111 | */ 112 | bool unique() const {return *refs == 1;} 113 | 114 | /** Returns the number of references. 115 | */ 116 | std::size_t use_count() const {return *refs;} 117 | 118 | /** Returns pointer to held object. 119 | */ 120 | type_t *get() const {return ptr;} 121 | 122 | protected: 123 | template 124 | friend counted_ptr make_counted(args_t &&...); 125 | 126 | // types 127 | using refs_t = std::size_t; 128 | 129 | /** C'tor: taking ownership. 130 | */ 131 | counted_ptr(type_t *ptr, refs_t *refs) noexcept 132 | : ptr(ptr), refs(refs) 133 | {} 134 | 135 | type_t *ptr; //!< pointer to the resource 136 | refs_t *refs; //!< pointer to the shared reference counter 137 | }; 138 | 139 | /** Factory function for counted ptr. 140 | */ 141 | template 142 | counted_ptr make_counted(args_t &&...args) { 143 | struct memory_t {type_t value; std::size_t refs;}; 144 | auto *bytes = new char[sizeof(memory_t)]; 145 | try { 146 | auto *memory = new (bytes) memory_t{{std::forward(args)...}, 1}; 147 | return counted_ptr(&memory->value, &memory->refs); 148 | } catch (...) {delete [] bytes; throw;} 149 | } 150 | 151 | /** Returns true if both pointers points to same object. 152 | */ 153 | template 154 | bool operator==(const counted_ptr &lhs, const counted_ptr &rhs) { 155 | return lhs.get() == rhs.get(); 156 | } 157 | 158 | /** Returns true if pointers doesn't point to same object. 159 | */ 160 | template 161 | bool operator!=(const counted_ptr &lhs, const counted_ptr &rhs) { 162 | return lhs.get() != rhs.get(); 163 | } 164 | 165 | } // namespace Teng 166 | 167 | #endif /* TENGCOUNTED_PTR_H */ 168 | 169 | -------------------------------------------------------------------------------- /src/dictionary.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Teng -- a general purpose templating engine. 3 | * Copyright (C) 2004 Seznam.cz, a.s. 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * Seznam.cz, a.s. 20 | * Naskove 1, Praha 5, 15000, Czech Republic 21 | * http://www.seznam.cz, mailto:teng@firma.seznam.cz 22 | * 23 | * 24 | * $Id: tengdictionary.h,v 1.3 2005-11-20 11:11:41 vasek Exp $ 25 | * 26 | * DESCRIPTION 27 | * Teng dictionary. 28 | * 29 | * AUTHORS 30 | * Vaclav Blazek 31 | * Michal Bukovsky 32 | * 33 | * HISTORY 34 | * 2003-09-18 (vasek) 35 | * Created. 36 | * 2018-06-14 (burlog) 37 | * Cleaned. 38 | */ 39 | 40 | #ifndef TENGDICTIONARY_H 41 | #define TENGDICTIONARY_H 42 | 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include "sourcelist.h" 49 | #include "teng/error.h" 50 | #include "teng/stringview.h" 51 | 52 | namespace Teng { 53 | 54 | /** 55 | * @short Dictionary -- mapping of string to string value. 56 | * 57 | * Used for language and parametric dictionaries. 58 | */ 59 | class Dictionary_t { 60 | public: 61 | /** 62 | * @short Creates new dictionary object. 63 | * 64 | * @param fs_root path of root for locating files 65 | */ 66 | Dictionary_t(Error_t &err, std::shared_ptr filesystem) 67 | : sources(), err(err), filesystem(filesystem), 68 | expandVars(false), replaceEntries(false) 69 | {} 70 | 71 | /** 72 | * @short Destroy dictionary object. 73 | */ 74 | virtual ~Dictionary_t() = default; 75 | 76 | /** 77 | * @short Searches for key in dictionary. 78 | * 79 | * @param key the key 80 | * @return found value or 0 when key not found 81 | */ 82 | virtual const std::string *lookup(const string_view_t &key) const; 83 | 84 | /** 85 | * @short Dumps dictionary into string. For debugging purposes. 86 | * 87 | * @param out output string 88 | */ 89 | void dump(std::string &out) const; 90 | 91 | /** 92 | * @short Dumps dictionary into stream. For debugging purposes. 93 | * 94 | * @param out output stream 95 | */ 96 | virtual void dump(std::ostream &out) const; 97 | 98 | /** 99 | * @short Return source list. 100 | * 101 | * @return source list 102 | */ 103 | const SourceList_t &getSources() const {return sources;} 104 | 105 | /** 106 | * @short Check source files for change. 107 | * 108 | * @return 0 OK !0 changed 109 | */ 110 | int isChanged() const {return sources.isChanged(filesystem.get());} 111 | 112 | /** 113 | * @short Fills dictionary with data parsed from filename. 114 | * 115 | * @param filename name of file to parse 116 | * @return 0 OK !0 error 117 | */ 118 | void parse(const std::string &filename); 119 | 120 | protected: 121 | // don't copy 122 | Dictionary_t(const Dictionary_t &) = delete; 123 | Dictionary_t &operator=(const Dictionary_t &) = delete; 124 | 125 | /** The result type for inserting parsed entry or directive. 126 | */ 127 | enum class error_code { 128 | none, 129 | unknown_directive, 130 | invalid_bool, 131 | invalid_number, 132 | invalid_enable, 133 | invalid_disable, 134 | }; 135 | 136 | /** Called when new entry parsed. 137 | * 138 | * Doesn't replace existing entry unless replaceEntries is set to true. 139 | */ 140 | virtual std::string * 141 | new_entry(const std::string &name, const std::string &value); 142 | 143 | /** Called when new directive parsed. 144 | */ 145 | virtual error_code 146 | new_directive( 147 | const char *name_ptr, std::size_t name_len, 148 | const char *value_ptr, std::size_t value_len 149 | ); 150 | 151 | // type for dictionary entries 152 | struct LocalCmp_t: std::less {struct is_transparent {};}; 153 | using Entries_t = std::map; 154 | 155 | Entries_t entries; //!< the dictionary entries 156 | SourceList_t sources; //!< source files of dictionary entries 157 | Error_t &err; //!< the error log 158 | std::shared_ptr filesystem; 159 | bool expandVars; //!< expand variables in dict values 160 | bool replaceEntries; //!< replace already present entries in dict 161 | }; 162 | 163 | } // namespace Teng 164 | 165 | #endif /* TENGDICTIONARY_H */ 166 | 167 | --------------------------------------------------------------------------------