/******************************************************************************** * Copyright (c) 2025-2026 ZF Friedrichshafen AG * * This program and the accompanying materials are made available under the * terms of the Apache License Version 2.0 which is available at * https://www.apache.org/licenses/LICENSE-2.0 * * SPDX-License-Identifier: Apache-2.0 * * Contributors: * Erik Verhoeven - initial API and implementation ********************************************************************************/ #ifndef CODEPOS_H #define CODEPOS_H #include "lexerbase.h" #include #include #include // Forward declaration class CToken; /** * @brief Code string with position information. */ class CCodePos { public: /** * @brief Default constructor * @remarks Use the assignment operator to set the code to be covered by the code position class. */ CCodePos(); /** * @brief Constructor * @param[in] szCode Pointer to zero terminated string containing the IDL code. Must not be NULL. */ CCodePos(const char* szCode); /** * @brief Copy constructor * @param[in] rCode Reference to the code to copy. */ CCodePos(const CCodePos& rCode); /** * @brief Move constructor * @param[in] rCode Reference to the code to move. */ CCodePos(CCodePos&& rCode) noexcept; /** * @{ * @brief Is the code position class initialized correctly? * @return Returns whether the class is initialized. */ bool IsValid() const; operator bool() const; /** * @} */ /** * @brief Reset the current navigation. * @attention Any prepended code will be removed. */ void Reset(); /** * @brief Return the current line. * @return The current line. */ uint32_t GetLine() const; /** * @brief Return the current column. * @return The current column. */ uint32_t GetCol() const; /** * @brief Check for EOF. * @return Returns 'true' when EOF has been reached. Otherwise returns 'false'. */ bool HasEOF() const; /** * @brief Check for EOL. * @return Returns 'true' when EOL has been reached. Otherwise returns 'false'. */ bool HasEOL() const; /** * @brief Get the token at the current location. * @attention The returned position is volatile and might be invalid as soon as code is prepended. Once the UpdateLocation * has been called, the code is persistent. * @param[in] eTokenType The type of token this token is referring to. * @return The token at the current location. */ CToken GetLocation(ETokenType eTokenType = ETokenType::token_none) const; /** * @{ * @brief Update the length of the token with current position. Persists the code if composed from (part of) prepended code. * @param[in, out] rtoken Reference to the token to be updated. */ void UpdateLocation(CToken& rtoken) const; /** * @brief Update the length of the token with current position. Persists the code if composed from (part of) prepended code. * @param[in, out] rtoken Reference to the token to be updated. * @param[in] eLiteralType The literal type to be assigned to the token (if any). */ void UpdateLocation(CToken& rtoken, ETokenLiteralType eLiteralType) const; /** * @brief Update the length of the token with current position. Persists the code if composed from (part of) prepended code. * @param[in, out] rtoken Reference to the token to be updated. * @param[in] eMetaType The meta type to be assigned to the token (if any). */ void UpdateLocation(CToken& rtoken, ETokenMetaType eMetaType) const; /** * @brief Insert code at the current position allowing to parse the prepended code. * @details This function prepends code at the current position. The code could be a macro expansion or precedence parsing. * @attention This function might invalidate tokens that have a start location, but no fixed location. * @param[in] rssCode Reference to a string object representing the code to prepend */ void PrependCode(const std::string& rssCode); /** * @brief Return whether the current position is part of the prepended code. * @return Returns 'true' when the current position is within the prepended code; otherwise returns 'false'. */ bool CurrentPositionInMacroExpansion() const; /** * @brief Assignment operator. * @param[in] rCode Reference to the code to copy. * @return Returns reference to this class. */ CCodePos& operator=(const CCodePos& rCode); /** * @brief Move operator. * @param[in] rCode Reference to the code to move. * @return Returns reference to this class. */ CCodePos& operator=(CCodePos&& rCode) noexcept; /** * @brief Get current character (with offset) * @param[in] uiOffset The offset of the character to read relative to the current character. * @attention The caller must make certain, that a valid character is available at the provided offset by interpreting the * characters before. * @return The current character or '\0' when there is no current character. */ char operator[](uint32_t uiOffset /*= 0*/) const; /** * @brief Get current character * @attention The caller must make certain, that a valid character is available at the provided offset by interpreting the * characters before. * @return The current character or '\0' when there is no current character. */ char operator*() const; /** * @brief Get the code at the current position. * @attention The caller must make certain, that a valid character is available at the provided offset by interpreting the * characters before. * @return Pointer to the code at the current location or nullptr when there is no code. */ operator const char*() const; /** * @brief Increment the current position * @return Copy of the code position before incrementation. */ CCodePos operator++(int); /** * @brief Increment the current position * @return Reference to this class. */ CCodePos& operator++(); /** * @brief Increment the current position * @param[in] uiOffset The offset of the character to increment to. * @return Reference to this class. */ CCodePos& operator+=(uint32_t uiOffset); private: const char* m_szCode = nullptr; ///< The code const char* m_szCurrent = nullptr; ///< The current position in the code const char* m_szPrependedPos = nullptr; ///< The position in the code where the prepended code is ///< inserted into. const char* m_szPrependedCode = nullptr; ///< The start position of the prepended code. const char* m_szPrependedCurrent = nullptr; ///< The current position in the prepended code; std::string m_ssPrependedCode; ///< The prepended code being returned before parsing of the ///< original code continues. mutable std::list m_lstCodeChunks; ///< List of code chunks existing of part or complete ///< prepended code. uint32_t m_uiLine = 0; ///< The current line uint32_t m_uiCol = 0; ///< The current column }; #endif // !defined CODEPOS_H