diff options
Diffstat (limited to 'src/lib/eval/eval_context.h')
-rw-r--r-- | src/lib/eval/eval_context.h | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/lib/eval/eval_context.h b/src/lib/eval/eval_context.h new file mode 100644 index 0000000..8050925 --- /dev/null +++ b/src/lib/eval/eval_context.h @@ -0,0 +1,249 @@ +// Copyright (C) 2015-2022 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EVAL_CONTEXT_H +#define EVAL_CONTEXT_H +#include <string> +#include <map> +#include <eval/parser.h> +#include <eval/eval_context_decl.h> +#include <exceptions/exceptions.h> + +// Tell Flex the lexer's prototype ... +#define YY_DECL \ + isc::eval::EvalParser::symbol_type evallex (EvalContext& driver) + +// ... and declare it for the parser's sake. +YY_DECL; + +namespace isc { +namespace eval { + +/// @brief Evaluation error exception raised when trying to parse an exceptions. +class EvalParseError : public isc::Exception { +public: + EvalParseError(const char* file, size_t line, const char* what) : + isc::Exception(file, line, what) { }; +}; + + +/// @brief Evaluation context, an interface to the expression evaluation. +class EvalContext { +public: + + /// @brief Specifies what type of expression the parser is expected to see + typedef enum { + PARSER_BOOL, ///< expression is expected to evaluate to bool + PARSER_STRING ///< expression is expected to evaluate to string + } ParserType; + + /// @brief Type of the check defined function. + typedef std::function<bool(const ClientClass&)> CheckDefined; + + /// @brief Default constructor. + /// + /// @param option_universe Option universe: DHCPv4 or DHCPv6. This is used + /// by the parser to determine which option definitions set should be used + /// to map option names to option codes. + /// @param check_defined A function called to check if a client class + /// used for membership is already defined. If it is not the parser + /// will fail: only backward or built-in references are accepted. + EvalContext(const Option::Universe& option_universe, + CheckDefined check_defined = acceptAll); + + /// @brief destructor + virtual ~EvalContext(); + + /// @brief Accept all client class names + /// + /// @param client_class (unused) + /// @return true + static bool acceptAll(const ClientClass& client_class); + + /// @brief Parsed expression (output tokens are stored here) + isc::dhcp::Expression expression; + + /// @brief Method called before scanning starts on a string. + /// + /// @param type specifies type of the expression to be parsed + void scanStringBegin(ParserType type); + + /// @brief Method called after the last tokens are scanned from a string. + void scanStringEnd(); + + /// @brief Run the parser on the string specified. + /// + /// @param str string to be parsed + /// @param type type of the expression expected/parser type to be created + /// @return true on success. + bool parseString(const std::string& str, ParserType type = PARSER_BOOL); + + /// @brief The name of the file being parsed. + /// Used later to pass the file name to the location tracker. + std::string file_; + + /// @brief The string being parsed. + std::string string_; + + /// @brief Error handler + /// + /// @param loc location within the parsed file where the problem was experienced. + /// @param what string explaining the nature of the error. + static void error(const isc::eval::location& loc, const std::string& what); + + /// @brief Error handler + /// + /// This is a simplified error reporting tool for possible future + /// cases when the EvalParser is not able to handle the packet. + static void error(const std::string& what); + + /// @brief Fatal error handler + /// + /// This is for should not happen but fatal errors + static void fatal(const std::string& what); + + /// @brief Option code conversion + /// + /// @param option_code a string representing the integer code + /// @param loc the location of the token + /// @result the option code + /// @throw calls the syntax error function if the value is not in + /// the range 0..255 or 0..65535 + uint16_t convertOptionCode(const std::string& option_code, + const isc::eval::location& loc); + + /// @brief Option name conversion + /// + /// @param option_name the option name + /// @param loc the location of the token + /// @return the option code + /// @throw calls the syntax error function if the name cannot be resolved + uint16_t convertOptionName(const std::string& option_name, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to unsigned 32bit integer + /// + /// For reverse conversion, see @ref fromUint32 + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static uint32_t convertUint32(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to signed 32bit integer + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static int32_t convertInt32(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to unsigned 16bit integer + /// + /// For reverse conversion, see @ref fromUint16 + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static uint16_t convertUint16(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to signed 16bit integer + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static int16_t convertInt16(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to unsigned 8bit integer + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static uint8_t convertUint8(const std::string& number, + const isc::eval::location& loc); + + /// @brief Attempts to convert string to signed 8bit integer + /// + /// @param number string to be converted + /// @param loc the location of the token + /// @return the integer value + /// @throw EvalParseError if conversion fails or the value is out of range. + static int8_t convertInt8(const std::string& number, + const isc::eval::location& loc); + + /// @brief Nest level conversion + /// + /// @param nest_level a string representing the integer nesting level + /// @param loc the location of the token + /// @return the nesting level + /// @throw calls the syntax error function if the value is not in + /// the range -32..31 + int8_t convertNestLevelNumber(const std::string& nest_level, + const isc::eval::location& loc); + + /// @brief Converts unsigned 32bit integer to string representation + /// + /// The integer is coded as a 4 byte long string in network order, e.g. + /// 6 is represented as 00000006. For reverse conversion, see + /// @ref convertUint32. + /// + /// @param integer value to be converted + /// @return 4 byte long string that encodes the value. + static std::string fromUint32(const uint32_t integer); + + /// @brief Converts unsigned 16bit integer to string representation + /// + /// The integer is coded as a 2 byte long string in network order, e.g. + /// 6 is represented as 0006. For reverse conversion, see + /// @ref convertUint16. + /// + /// @param integer value to be converted + /// @return 2 byte long string that encodes the value. + static std::string fromUint16(const uint16_t integer); + + /// @brief Returns the universe (v4 or v6) + /// + /// @return universe + Option::Universe getUniverse() { + return (option_universe_); + } + + /// @brief Check if a client class is already defined + /// + /// @param client_class the client class name to check + /// @return true if the client class is defined, false if not + bool isClientClassDefined(const ClientClass& client_class); + +private: + /// @brief Flag determining scanner debugging. + bool trace_scanning_; + + /// @brief Flag determining parser debugging. + bool trace_parsing_; + + /// @brief Option universe: DHCPv4 or DHCPv6. + /// + /// This is used by the parser to determine which option definitions + /// set should be used to map option name to option code. + Option::Universe option_universe_; + + /// @brief Function to check if a client class is already defined. + CheckDefined check_defined_; + +}; + +} // end of isc::eval namespace +} // end of isc namespace + +#endif |