summaryrefslogtreecommitdiffstats
path: root/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/chunk.h
diff options
context:
space:
mode:
Diffstat (limited to 'debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/chunk.h')
-rw-r--r--debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/chunk.h1262
1 files changed, 1262 insertions, 0 deletions
diff --git a/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/chunk.h b/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/chunk.h
new file mode 100644
index 00000000..cf3b987f
--- /dev/null
+++ b/debian/uncrustify-trinity/uncrustify-trinity-0.75.0/src/chunk.h
@@ -0,0 +1,1262 @@
+/**
+ * @file chunk.h
+ * Manages and navigates the list of chunks.
+ *
+ * @author Ben Gardner
+ * @license GPL v2+
+ */
+
+#ifndef CHUNK_LIST_H_INCLUDED
+#define CHUNK_LIST_H_INCLUDED
+
+#include "uncrustify_types.h"
+// necessary to not sort it
+#include "char_table.h"
+#include "language_tools.h"
+
+
+/*
+ * TODO: better use a namespace for all chunk related operations.
+ * The function "chunk_is_comment()" would for instance
+ * become "chunk::is_comment()". This makes the usage of the chunks easier
+ * and more intuitive.
+ */
+
+
+static constexpr int ANY_LEVEL = -1;
+
+
+/**
+ * Specifies which chunks should/should not be found.
+ * ALL (default)
+ * - return the true next/prev
+ *
+ * PREPROC
+ * - If not in a preprocessor, skip over any encountered preprocessor stuff
+ * - If in a preprocessor, fail to leave (return nullptr)
+ */
+enum class E_Scope : unsigned int
+{
+ ALL, //! search in all kind of chunks
+ PREPROC, //! search only in preprocessor chunks
+};
+
+
+/**
+ * Specifies which direction or location an operation shall be performed.
+ */
+enum class E_Direction : unsigned int
+{
+ FORWARD,
+ BACKWARD
+};
+
+
+/**
+ * Temporary internal typedef. Will be progressively be replaced by Chunk::CheckFnPtr.
+ *
+ * @brief prototype for a function that checks a chunk to have a given type
+ *
+ * @note this typedef defines the function type "check_t"
+ * for a function pointer of type
+ * bool function(Chunk *pc)
+ */
+// TODO remove when finished
+typedef bool (*check_t)(Chunk *pc);
+
+
+// This is the main type of this program
+class Chunk
+{
+public:
+ static Chunk NullChunk; // Null Chunk
+ static Chunk *const NullChunkPtr; // Pointer to the Null Chunk
+
+ //! constructors
+ Chunk(bool null_c = false); // default
+ Chunk(const Chunk &o); // !!! partial copy: chunk is not linked to others
+
+ Chunk &operator=(const Chunk &o); // !!! partial copy: chunk is not linked to others
+
+ //! whether this is a null Chunk or not
+ bool IsNullChunk() const { return(null_chunk); }
+ bool IsNotNullChunk() const { return(!null_chunk); }
+
+ //! sets all elements of the struct to their default value
+ void Reset();
+
+ //! provides the number of characters of string
+ size_t Len() const;
+
+ //! provides the content of a string a zero terminated character pointer
+ const char *Text() const;
+
+ // Issue #2984, fill up, if necessary, a copy of the first chars of the Text() string
+ const char *ElidedText(char *for_the_copy) const;
+
+
+ // --------- Get* chunk functions
+
+ /**
+ * @brief returns the head of the chunk list
+ * @return pointer to the first chunk
+ */
+ static Chunk *GetHead(void);
+
+ /**
+ * @brief returns the tail of the chunk list
+ * @return pointer to the last chunk
+ */
+ static Chunk *GetTail(void);
+
+ /**
+ * @brief returns the next chunk in a list of chunks
+ * @param scope code region to search in
+ * @return pointer to next chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNext(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the previous chunk in a list of chunks
+ * @param scope code region to search in
+ * @return pointer to previous chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrev(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next newline chunk
+ * @param scope code region to search in
+ * @return pointer to next newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev newline chunk
+ * @param scope code region to search in
+ * @return pointer to prev newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next non-newline chunk
+ * @param scope code region to search in
+ * @return pointer to next non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNnl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev non-newline chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNnl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next non-comment chunk
+ * @param scope code region to search in
+ * @return pointer to next non-comment chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNc(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev non-comment chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-comment chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNc(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next non-comment and non-newline chunk
+ * @param scope code region to search in
+ * @return pointer to next non-comment and non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNcNnl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev non-comment and non-newline chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-comment and non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNcNnl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next non-comment, non-newline, non-preprocessor chunk
+ * @param scope code region to search in
+ * @return pointer to next non-comment, non-newline, non-preprocessor chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNcNnlNpp(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev non-comment, non-newline, non-preprocessor chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-comment, non-newline, non-preprocessor chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNcNnlNpp(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next non-preprocessor or non-comment, non-newline chunk
+ * @param scope code region to search in
+ * @return pointer to next non-preprocessor or non-comment, non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNppOrNcNnl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev non-preprocessor or non-comment, non-newline chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-preprocessor or non-comment, non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNppOrNcNnl(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the next preprocessor aware non-comment and non-newline chunk
+ * Unlike Chunk::GetNextNcNnl, this will also ignore a line continuation if
+ * the starting chunk is in a preprocessor directive, and may return a newline
+ * if the search reaches the end of a preprocessor directive.
+ * @return pointer to next preprocessor aware non-comment and non-newline chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *PpaGetNextNcNnl() const;
+
+ /**
+ * @brief returns the next non-comment, non-newline, non-empty text chunk
+ * @param scope code region to search in
+ * @return pointer to next non-comment, non-newline, non-empty text chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNcNnlNet(const E_Scope scope = E_Scope::ALL) const;
+
+ /**
+ * @brief returns the prev non-comment, non-newline, non-empty text chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-comment, non-newline, non-empty text chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNcNnlNet(const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the prev non-comment, non-newline, non-ignored chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-comment, non-newline, non-ignored chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNcNnlNi(const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the next chunk not in or part of balanced square
+ * brackets. This handles stacked [] instances to accommodate
+ * multi-dimensional array declarations
+ * @param scope code region to search in
+ * @return nullptr or the next chunk not in or part of square brackets
+ */
+ Chunk *GetNextNisq(const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the next non-virtual brace chunk
+ * @param scope code region to search in
+ * @return pointer to next non-virtual brace chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextNvb(const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the prev non-virtual brace chunk
+ * @param scope code region to search in
+ * @return pointer to prev non-virtual brace chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevNvb(const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the next chunk of the given type at the level.
+ * @param cType the type to look for
+ * @param cLevel the level to match, -1 or ANY_LEVEL (any level)
+ * @param scope code region to search in
+ * @return pointer to the next matching chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextType(const E_Token cType, const int cLevel, const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the prev chunk of the given type at the level.
+ * @param cType the type to look for
+ * @param cLevel the level to match, -1 or ANY_LEVEL (any level)
+ * @param scope code region to search in
+ * @return pointer to the prev matching chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevType(const E_Token type, int level, E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the next chunk that holds a given string at a given level.
+ * @param cStr string to search for
+ * @param len length of string
+ * @param cLevel -1 or ANY_LEVEL (any level) or the level to match
+ * @param scope code region to search in
+ * @return pointer to the next matching chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetNextString(const char *cStr, const size_t len, const int cLevel, const E_Scope scope = E_Scope::ALL) const;
+
+
+ /**
+ * @brief returns the prev chunk that holds a given string at a given level.
+ * @param cStr string to search for
+ * @param len length of string
+ * @param cLevel -1 or ANY_LEVEL (any level) or the level to match
+ * @param scope code region to search in
+ * @return pointer to the prev matching chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *GetPrevString(const char *cStr, const size_t len, const int cLevel, const E_Scope scope = E_Scope::ALL) const;
+
+
+ // --------- Search functions
+
+ /**
+ * @brief defines a member function pointer for a function of type
+ * Chunk *Chunk::function(const E_Scope scope)
+ * that will search for a new chunk
+ */
+ typedef Chunk *(Chunk::*T_SearchFnPtr)(const E_Scope scope) const;
+
+ /**
+ * @brief defines a member function pointer for a function of type
+ * bool Chunk::function() const;
+ * that checks whether a chunk satisty a specific condition
+ */
+ typedef bool (Chunk::*T_CheckFnPtr)() const;
+
+ /**
+ * @brief determines the search direction to use and returns a pointer
+ * to the corresponding search function.
+ * @param dir search direction
+ * @return pointer to search function
+ */
+ static T_SearchFnPtr GetSearchFn(const E_Direction dir = E_Direction::FORWARD);
+
+ /**
+ * @brief search for a chunk that satisfies a condition in a chunk list
+ *
+ * A generic function that traverses a chunks list either
+ * in forward or reverse direction. The traversal continues until a
+ * chunk satisfies the condition defined by the compare function.
+ * Depending on the parameter cond the condition will either be
+ * checked to be true or false.
+ *
+ * @param checkFn compare function
+ * @param scope code parts to consider for search
+ * @param dir search direction (forward or backward)
+ * @param cond success condition
+ *
+ * @return pointer to the found chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *Search(const T_CheckFnPtr checkFn, const E_Scope scope = E_Scope::ALL, const E_Direction dir = E_Direction::FORWARD, const bool cond = true) const;
+
+ /**
+ * @brief search for a chunk that satisfies a condition in a chunk list,
+ * but being aware of preprocessor chucks.
+ *
+ * This function is similar to Search, except that it is tweaked to
+ * handle searches inside of preprocessor directives. Specifically, if the
+ * starting token is inside a preprocessor directive, it will ignore a line
+ * continuation, and will abort the search if it reaches the end of the
+ * directive. This function only searches forward.
+ *
+ * @param checkFn compare function
+ * @param cond success condition
+ *
+ * @return pointer to the found chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *SearchPpa(const T_CheckFnPtr checkFn, const bool cond = true) const;
+
+ /**
+ * @brief search a chunk of a given type and level. Traverses a chunk list in the
+ * specified direction until a chunk of a given type is found.
+ *
+ * This function is a specialization of Chunk::Search.
+ *
+ * @param cType category to search for
+ * @param scope code parts to consider for search
+ * @param dir search direction
+ * @param cLevel nesting level to match or -1 / ANY_LEVEL
+ *
+ * @return pointer to the found chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *SearchTypeLevel(const E_Token cType, const E_Scope scope = E_Scope::ALL, const E_Direction dir = E_Direction::FORWARD, const int cLevel = -1) const;
+
+
+ /**
+ * @brief searches a chunk that holds a specific string
+ *
+ * Traverses a chunk list either in forward or backward direction until a chunk
+ * with the provided string was found. Additionally a nesting level can be
+ * provided to narrow down the search.
+ *
+ * @param cStr string that searched chunk needs to have
+ * @param len length of the string
+ * @param cLevel nesting level of the searched chunk, ignored when negative
+ * @param scope code parts to consider for search
+ * @param dir search direction
+ *
+ * @return pointer to the found chunk or Chunk::NullChunkPtr if no chunk was found
+ */
+ Chunk *SearchStringLevel(const char *cStr, const size_t len, const int cLevel, const E_Scope scope = E_Scope::ALL, const E_Direction dir = E_Direction::FORWARD) const;
+
+
+ // --------- Is* functions
+
+ /**
+ * @brief checks whether the chunk is a specific token
+ * @token the token to check for
+ * @return true if the chunk type matches the specified token, false otherwise
+ */
+ bool Is(E_Token token) const;
+
+ /**
+ * @brief checks whether the chunk is not a specific token
+ * @token the token to check for
+ * @return true if the chunk type does not matches the specified token, false otherwise
+ */
+ bool IsNot(E_Token token) const;
+
+ /**
+ * @brief checks whether the chunk is a newline
+ * @return true if the chunk is a newline, false otherwise
+ */
+ bool IsNewline() const;
+
+ /**
+ * @brief checks whether the chunk is a comment
+ * This means any kind of:
+ * - single line comment
+ * - multiline comment
+ * - C comment
+ * - C++ comment
+ */
+ bool IsComment() const;
+
+ /**
+ * @brief checks whether the chunk is valid and has an empty text
+ * @return true if the chunk is valid and has an empty text
+ */
+ bool IsEmptyText() const;
+
+ /**
+ * @brief checks whether the chunk is a preprocessor
+ * @return true if the chunk is a preprocessor, false otherwise
+ */
+ bool IsPreproc() const;
+
+ /**
+ * @brief checks whether the chunk is either a comment or a newline
+ * @return true if the chunk is either a comment or a newline, false otherwise
+ */
+ bool IsCommentOrNewline() const;
+
+ /**
+ * @brief checks whether the chunk is either a comment, a newline or ignored
+ * @return true if the chunk is either a comment, a newline or ignored, false otherwise
+ */
+ bool IsCommentNewlineOrIgnored() const;
+
+ /**
+ * @brief checks whether the chunk is a comment, a newline or a preprocessor
+ * @return true if the chunk is a comment, a newline or a preprocessor, false otherwise
+ */
+ bool IsCommentNewlineOrPreproc() const;
+
+ /**
+ * @brief checks whether the chunk is a preprocessor and either a comment or a newline
+ * @return true if the chunk is a preprocessor and either a comment or a newline, false otherwise
+ */
+ bool IsCommentOrNewlineInPreproc() const;
+
+ /**
+ * @brief checks whether the chunk is a comment, a newline or has an empty text
+ * @return true if the chunk is a comment, a newline or has an empty text
+ */
+ bool IsCommentNewlineOrEmptyText() const;
+
+ /**
+ * @brief checks whether the chunk is a square bracket
+ * @return true if the chunk is a square bracket
+ */
+ bool IsSquareBracket() const;
+
+ /**
+ * @brief checks whether the chunk is a virtual brace
+ * @return true if the chunk is a virtual brace
+ */
+ bool IsVBrace() const;
+
+ /**
+ * @brief checks whether the chunk matches a given type and level
+ * @param type category to search for
+ * @param level nesting level to match
+ * @return true if the chunk matches a given type and level
+ */
+ bool IsTypeAndLevel(const E_Token cType, const int cLevel) const;
+
+
+ /**
+ * @brief checks whether the chunk matches a given string and level
+ * @param cStr the expected string
+ * @param len length of the string
+ * @param cLevel nesting level of the searched chunk, ignored when negative
+ * @return true if the chunk matches a given string and level
+ */
+ bool IsStringAndLevel(const char *cStr, const size_t len, const int cLevel) const;
+
+
+ /**
+ * @brief checks whether the chunk is a star/asterisk
+ * @return true if the chunk is a star/asterisk
+ */
+ bool IsStar() const;
+
+
+ // --------- Data members
+
+ Chunk *next; //! pointer to next chunk in list
+ Chunk *prev; //! pointer to previous chunk in list
+ Chunk *parent; //! pointer to parent chunk(not always set)
+
+ align_ptr_t align;
+ indent_ptr_t indent;
+ E_Token type; //! type of the chunk itself
+ E_Token parent_type; //! type of the parent chunk usually CT_NONE
+ //! might be different from parent->parent_type (above)
+ size_t orig_line; //! line number of chunk in input file
+ size_t orig_col; //! column where chunk started in the input file, is always > 0
+ size_t orig_col_end; //! column where chunk ended in the input file, is always > 1
+ UINT32 orig_prev_sp; //! whitespace before this token
+ pcf_flags_t flags; //! see PCF_xxx
+ size_t column; //! column of chunk
+ size_t column_indent; /** if 1st on a line, set to the 'indent'
+ * column, which may be less than the real
+ * column used to indent with tabs */
+ size_t nl_count; //! number of newlines in CT_NEWLINE
+ size_t nl_column; //! column of the subsequent newline entries(all of them should have the same column)
+ size_t level; /** nest level in {, (, or [
+ * only to help vim command } */
+ size_t brace_level; //! nest level in braces only
+ size_t pp_level; //! nest level in preprocessor
+ bool after_tab; //! whether this token was after a tab
+ unc_text str; //! the token text
+
+ // for debugging purpose only
+ track_list *tracking;
+
+private:
+ void copyFrom(const Chunk &o); // !!! partial copy: chunk is not linked to others
+
+ const bool null_chunk; //! true for null chunks
+};
+
+
+/**
+ * @brief Add a copy of a chunk to a chunk list after the given position.
+ *
+ * @note If ref is nullptr, add at the tail of the chunk list
+ *
+ * @todo is ref=nullptr really useful ?
+ *
+ * @param pc_in pointer to chunk to add to list
+ * @param ref position where insertion takes place
+ *
+ * @return pointer to the added chunk
+ */
+Chunk *chunk_add_after(const Chunk *pc_in, Chunk *ref);
+
+
+/**
+ * @brief Add a copy of a chunk to a chunk list before the given position
+ *
+ * @note If ref is nullptr, add at the head of the chunk list
+ *
+ * @todo is ref=nullptr really useful ?
+ *
+ * \bug code adds it before the tail, either code or comment is wrong
+ *
+ * @param pc_in pointer to chunk to add to list
+ * @param ref position where insertion takes place
+ *
+ * @retval pointer to the added chunk
+ */
+Chunk *chunk_add_before(const Chunk *pc_in, Chunk *ref);
+
+
+/**
+ * delete a chunk from a chunk list
+ *
+ * @param pc chunk to delete
+ */
+void chunk_del(Chunk * &pc);
+
+
+/**
+ * move a chunk to after the reference position in a chunk list
+ *
+ * @param pc_in chunk to move
+ * @param ref chunk after which to move
+ */
+void chunk_move_after(Chunk *pc_in, Chunk *ref);
+
+
+/**
+ * Swaps two chunks
+ *
+ * @param pc1 The first chunk
+ * @param pc2 The second chunk
+ */
+void chunk_swap(Chunk *pc1, Chunk *pc2);
+
+
+/**
+ * Swaps two lines that are started with the specified chunks.
+ *
+ * @param pc1 The first chunk of line 1
+ * @param pc2 The first chunk of line 2
+ */
+void chunk_swap_lines(Chunk *pc1, Chunk *pc2);
+
+
+/**
+ * Finds the first chunk on the line that pc is on.
+ * This just backs up until a newline or nullptr is hit.
+ *
+ * given: [ a - b - c - n1 - d - e - n2 ]
+ * input: [ a | b | c | n1 ] => a
+ * input: [ d | e | n2 ] => d
+ *
+ * @param pc chunk to start with
+ */
+Chunk *chunk_first_on_line(Chunk *pc);
+
+
+//! check if a given chunk is the last on its line
+bool chunk_is_last_on_line(Chunk *pc);
+
+
+/**
+ * Gets the next chunk not in or part of balanced square
+ * brackets.This handles stacked[] instances to accommodate
+ * multi - dimensional array declarations
+ *
+ * @param cur chunk to use as start point
+ *
+ * @return nullptr or the next chunk not in or part of square brackets
+ */
+Chunk *chunk_get_next_ssq(Chunk *cur);
+
+/**
+ * Gets the prev chunk not in or part of balanced square
+ * brackets.This handles stacked[] instances to accommodate
+ * multi - dimensional array declarations
+ *
+ * @param cur chunk to use as start point
+ *
+ * @return nullptr or the prev chunk not in or part of square brackets
+ */
+Chunk *chunk_get_prev_ssq(Chunk *cur);
+
+
+/**
+ * Gets the corresponding start chunk if the given chunk is within a
+ * preprocessor directive, or nullptr otherwise.
+ *
+ * @param cur chunk to use as start point
+ *
+ * @return nullptr or start chunk of the preprocessor directive
+ */
+Chunk *chunk_get_pp_start(Chunk *cur);
+
+
+/**
+ * @brief reverse search a chunk of a given category in a chunk list
+ *
+ * @param pc chunk list to search in
+ * @param cat category to search for
+ *
+ * @retval nullptr no object found, or invalid parameters provided
+ * @retval Chunk pointer to the found object
+ */
+Chunk *chunk_search_prev_cat(Chunk *pc, const E_Token cat);
+
+
+/**
+ * @brief forward search a chunk of a given category in a chunk list
+ *
+ * @param pc chunk list to search in
+ * @param cat category to search for
+ *
+ * @retval nullptr no object found, or invalid parameters provided
+ * @retval Chunk pointer to the found object
+ */
+Chunk *chunk_search_next_cat(Chunk *pc, const E_Token cat);
+
+
+/**
+ * @brief checks wether two chunks are in same line
+ *
+ * @param start
+ * @param end
+ *
+ * @return true if there is no newline between start and end chunks
+ */
+bool are_chunks_in_same_line(Chunk *start, Chunk *end);
+
+
+inline bool Chunk::IsTypeAndLevel(const E_Token cType, const int cLevel) const
+{
+ return( ( cLevel < 0
+ || level == static_cast<size_t>(cLevel))
+ && type == cType);
+}
+
+
+inline bool Chunk::IsStringAndLevel(const char *cStr, const size_t len, const int cLevel) const
+{
+ return( ( cLevel < 0
+ || level == static_cast<size_t>(cLevel))
+ && Len() == len // the length is as expected
+ && memcmp(cStr, Text(), len) == 0); // the strings are equal
+}
+
+
+inline bool Chunk::Is(E_Token token) const
+{
+ return( IsNotNullChunk()
+ && type == token);
+}
+
+
+inline bool Chunk::IsNot(E_Token token) const
+{
+ return(!Is(token));
+}
+
+
+inline bool Chunk::IsNewline() const
+{
+ return( Is(CT_NEWLINE)
+ || Is(CT_NL_CONT));
+}
+
+
+inline bool Chunk::IsComment() const
+{
+ return( Is(CT_COMMENT)
+ || Is(CT_COMMENT_MULTI)
+ || Is(CT_COMMENT_CPP));
+}
+
+
+inline bool Chunk::IsEmptyText() const
+{
+ return( IsNotNullChunk()
+ && Len() == 0);
+}
+
+
+inline bool Chunk::IsPreproc() const
+{
+ return( IsNotNullChunk()
+ && flags.test(PCF_IN_PREPROC));
+}
+
+
+inline bool Chunk::IsCommentOrNewline() const
+{
+ return( IsComment()
+ || IsNewline());
+}
+
+
+inline bool Chunk::IsCommentNewlineOrPreproc() const
+{
+ return( IsComment()
+ || IsNewline()
+ || IsPreproc());
+}
+
+
+inline bool Chunk::IsCommentOrNewlineInPreproc() const
+{
+ return( IsPreproc()
+ && ( IsComment()
+ || IsNewline()));
+}
+
+
+inline bool Chunk::IsCommentNewlineOrEmptyText() const
+{
+ return( IsComment()
+ || IsNewline()
+ || IsEmptyText());
+}
+
+
+inline bool Chunk::IsCommentNewlineOrIgnored() const
+{
+ return( IsComment()
+ || IsNewline()
+ || Is(CT_IGNORED));
+}
+
+
+inline bool Chunk::IsSquareBracket() const
+{
+ return( Is(CT_SQUARE_OPEN)
+ || Is(CT_TSQUARE)
+ || Is(CT_SQUARE_CLOSE));
+}
+
+
+inline bool Chunk::IsVBrace() const
+{
+ return( Is(CT_VBRACE_OPEN)
+ || Is(CT_VBRACE_CLOSE));
+}
+
+
+inline bool Chunk::IsStar() const
+{
+ return( Len() == 1
+ && str[0] == '*'
+ && IsNot(CT_OPERATOR_VAL));
+}
+
+
+// TODO remove when possible
+static inline bool chunk_is_token(const Chunk *pc, E_Token c_token)
+{
+ return( pc != nullptr
+ && pc->IsNotNullChunk()
+ && pc->type == c_token);
+}
+
+
+// TODO remove when possible
+static inline bool chunk_is_not_token(const Chunk *pc, E_Token c_token)
+{
+ return( pc != nullptr
+ && pc->IsNotNullChunk()
+ && pc->type != c_token);
+}
+
+
+/**
+ * Skips to the closing match for the current paren/brace/square.
+ *
+ * @param cur The opening or closing paren/brace/square
+ * @param scope chunk section to consider
+ *
+ * @return nullptr or the matching paren/brace/square
+ */
+static inline Chunk *chunk_skip_to_match(Chunk *cur, E_Scope scope = E_Scope::ALL)
+{
+ if ( cur != nullptr
+ && ( chunk_is_token(cur, CT_PAREN_OPEN)
+ || chunk_is_token(cur, CT_SPAREN_OPEN)
+ || chunk_is_token(cur, CT_FPAREN_OPEN)
+ || chunk_is_token(cur, CT_TPAREN_OPEN)
+ || chunk_is_token(cur, CT_BRACE_OPEN)
+ || chunk_is_token(cur, CT_VBRACE_OPEN)
+ || chunk_is_token(cur, CT_ANGLE_OPEN)
+ || chunk_is_token(cur, CT_SQUARE_OPEN)))
+ {
+ return(cur->GetNextType((E_Token)(cur->type + 1), cur->level, scope));
+ }
+ return(cur);
+}
+
+
+static inline Chunk *chunk_skip_to_match_rev(Chunk *cur, E_Scope scope = E_Scope::ALL)
+{
+ if ( cur != nullptr
+ && ( chunk_is_token(cur, CT_PAREN_CLOSE)
+ || chunk_is_token(cur, CT_SPAREN_CLOSE)
+ || chunk_is_token(cur, CT_FPAREN_CLOSE)
+ || chunk_is_token(cur, CT_TPAREN_CLOSE)
+ || chunk_is_token(cur, CT_BRACE_CLOSE)
+ || chunk_is_token(cur, CT_VBRACE_CLOSE)
+ || chunk_is_token(cur, CT_ANGLE_CLOSE)
+ || chunk_is_token(cur, CT_SQUARE_CLOSE)))
+ {
+ return(cur->GetPrevType((E_Token)(cur->type - 1), cur->level, scope));
+ }
+ return(cur);
+}
+
+
+//! skip to the final word/type in a :: chain
+Chunk *chunk_skip_dc_member(Chunk *start, E_Scope scope = E_Scope::ALL);
+Chunk *chunk_skip_dc_member_rev(Chunk *start, E_Scope scope = E_Scope::ALL);
+
+
+/**
+ * Returns true if the chunk under test is an inheritance access specifier
+ */
+static inline bool chunk_is_cpp_inheritance_access_specifier(Chunk *pc)
+{
+ return( language_is_set(LANG_CPP)
+ && pc != nullptr
+ && pc->IsNotNullChunk()
+ && ( chunk_is_token(pc, CT_ACCESS)
+ || chunk_is_token(pc, CT_QUALIFIER))
+ && ( std::strncmp(pc->str.c_str(), "private", 7) == 0
+ || std::strncmp(pc->str.c_str(), "protected", 9) == 0
+ || std::strncmp(pc->str.c_str(), "public", 6) == 0));
+} // chunk_is_cpp_inheritance_access_specifier
+
+
+static inline bool chunk_is_colon(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_ACCESS_COLON)
+ || chunk_is_token(pc, CT_ASM_COLON)
+ || chunk_is_token(pc, CT_BIT_COLON)
+ || chunk_is_token(pc, CT_CASE_COLON)
+ || chunk_is_token(pc, CT_CLASS_COLON)
+ || chunk_is_token(pc, CT_COLON)
+ || chunk_is_token(pc, CT_COND_COLON)
+ || chunk_is_token(pc, CT_CONSTR_COLON)
+ || chunk_is_token(pc, CT_CS_SQ_COLON)
+ || chunk_is_token(pc, CT_D_ARRAY_COLON)
+ || chunk_is_token(pc, CT_FOR_COLON)
+ || chunk_is_token(pc, CT_LABEL_COLON)
+ || chunk_is_token(pc, CT_OC_COLON)
+ || chunk_is_token(pc, CT_OC_DICT_COLON)
+ || chunk_is_token(pc, CT_TAG_COLON)
+ || chunk_is_token(pc, CT_WHERE_COLON));
+}
+
+
+static inline bool chunk_is_single_line_comment(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_COMMENT)
+ || chunk_is_token(pc, CT_COMMENT_CPP));
+}
+
+
+// TODO remove when possible
+static inline bool chunk_is_newline(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_NEWLINE)
+ || chunk_is_token(pc, CT_NL_CONT));
+}
+
+
+static inline bool chunk_is_semicolon(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_SEMICOLON)
+ || chunk_is_token(pc, CT_VSEMICOLON));
+}
+
+
+static inline bool chunk_is_Doxygen_comment(Chunk *pc)
+{
+ if ( pc == nullptr
+ || !pc->IsComment())
+ {
+ return(false);
+ }
+ // check the third character
+ const char *sComment = pc->Text();
+ const size_t len = strlen(sComment);
+
+ if (len < 3)
+ {
+ return(false);
+ }
+ return( (sComment[2] == '/')
+ || (sComment[2] == '!')
+ || (sComment[2] == '@'));
+}
+
+
+static inline bool chunk_is_type(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_TYPE)
+ || chunk_is_token(pc, CT_PTR_TYPE)
+ || chunk_is_token(pc, CT_BYREF)
+ || chunk_is_token(pc, CT_DC_MEMBER)
+ || chunk_is_token(pc, CT_QUALIFIER)
+ || chunk_is_token(pc, CT_STRUCT)
+ || chunk_is_token(pc, CT_ENUM)
+ || chunk_is_token(pc, CT_UNION));
+}
+
+
+static inline bool chunk_is_str(Chunk *pc, const char *str)
+{
+ size_t len = strlen(str);
+
+ return( pc != nullptr // valid pc pointer
+ && (pc->Len() == len) // token size equals size parameter
+ && (memcmp(pc->Text(), str, len) == 0)); // token name is the same as str parameter
+
+ /*
+ * TODO: possible access beyond array for memcmp, check this
+ * why not use strncmp here?
+ */
+}
+
+
+static inline bool chunk_is_str_case(Chunk *pc, const char *str, size_t len)
+{
+ return( pc != nullptr
+ && (pc->Len() == len)
+ && (strncasecmp(pc->Text(), str, len) == 0));
+}
+
+
+static inline bool chunk_is_word(Chunk *pc)
+{
+ return( pc != nullptr
+ && (pc->Len() >= 1)
+ && CharTable::IsKw1(pc->str[0]));
+}
+
+
+static inline bool chunk_is_nullable(Chunk *pc)
+{
+ return( language_is_set(LANG_CS | LANG_VALA)
+ && (pc != nullptr)
+ && (pc->Len() == 1)
+ && (pc->str[0] == '?'));
+}
+
+
+static inline bool chunk_is_addr(Chunk *pc)
+{
+ if ( pc != nullptr
+ && pc->IsNotNullChunk()
+ && ( chunk_is_token(pc, CT_BYREF)
+ || ( (pc->Len() == 1)
+ && (pc->str[0] == '&')
+ && pc->type != CT_OPERATOR_VAL)))
+ {
+ Chunk *prev = pc->GetPrev();
+
+ if ( pc->flags.test(PCF_IN_TEMPLATE)
+ && ( chunk_is_token(prev, CT_COMMA)
+ || chunk_is_token(prev, CT_ANGLE_OPEN)))
+ {
+ return(false);
+ }
+ return(true);
+ }
+ return(false);
+}
+
+
+static inline bool chunk_is_msref(Chunk *pc) // ms compilers for C++/CLI and WinRT use '^' instead of '*' for marking up reference types vs pointer types
+{
+ return( language_is_set(LANG_CPP)
+ && ( pc != nullptr
+ && (pc->Len() == 1)
+ && (pc->str[0] == '^')
+ && pc->type != CT_OPERATOR_VAL));
+}
+
+
+static inline bool chunk_is_ptr_operator(Chunk *pc)
+{
+ return( pc != nullptr
+ && ( ( pc->IsStar()
+ || chunk_is_addr(pc)
+ || chunk_is_msref(pc))
+ || chunk_is_nullable(pc)));
+}
+
+
+static inline bool chunk_is_pointer_or_reference(Chunk *pc)
+{
+ return( chunk_is_ptr_operator(pc)
+ || chunk_is_token(pc, CT_BYREF));
+}
+
+
+//! Check to see if there is a newline between the two chunks
+bool chunk_is_newline_between(Chunk *start, Chunk *end);
+
+
+static inline bool chunk_is_closing_brace(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_BRACE_CLOSE)
+ || chunk_is_token(pc, CT_VBRACE_CLOSE));
+}
+
+
+static inline bool chunk_is_opening_brace(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_BRACE_OPEN)
+ || chunk_is_token(pc, CT_VBRACE_OPEN));
+}
+
+
+static inline bool chunk_is_paren_open(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_PAREN_OPEN)
+ || chunk_is_token(pc, CT_SPAREN_OPEN)
+ || chunk_is_token(pc, CT_TPAREN_OPEN)
+ || chunk_is_token(pc, CT_FPAREN_OPEN)
+ || chunk_is_token(pc, CT_LPAREN_OPEN));
+}
+
+
+static inline bool chunk_is_paren_close(Chunk *pc)
+{
+ return( chunk_is_token(pc, CT_PAREN_CLOSE)
+ || chunk_is_token(pc, CT_SPAREN_CLOSE)
+ || chunk_is_token(pc, CT_TPAREN_CLOSE)
+ || chunk_is_token(pc, CT_FPAREN_CLOSE));
+}
+
+
+/**
+ * Returns true if either chunk is null or both have the same preproc flags.
+ * If this is true, you can remove a newline/nl_cont between the two.
+ */
+static inline bool chunk_same_preproc(Chunk *pc1, Chunk *pc2)
+{
+ return( pc1 == nullptr
+ || pc1->IsNullChunk()
+ || pc2 == nullptr
+ || pc2->IsNullChunk()
+ || ((pc1->flags & PCF_IN_PREPROC) == (pc2->flags & PCF_IN_PREPROC)));
+}
+
+
+/**
+ * Returns true if it is safe to delete the newline token.
+ * The prev and next chunks must have the same PCF_IN_PREPROC flag AND
+ * the newline can't be after a C++ comment.
+ */
+static inline bool chunk_safe_to_del_nl(Chunk *nl)
+{
+ if (nl == nullptr)
+ {
+ nl = Chunk::NullChunkPtr;
+ }
+ Chunk *tmp = nl->GetPrev();
+
+ if (chunk_is_token(tmp, CT_COMMENT_CPP))
+ {
+ return(false);
+ }
+ return(chunk_same_preproc(tmp, nl->GetNext()));
+}
+
+
+/**
+ * Checks if a chunk points to the opening parenthese of a
+ * for(...in...) loop in Objective-C.
+ *
+ * @return true - the chunk is the opening parentheses of a for in loop
+ */
+static inline bool chunk_is_forin(Chunk *pc)
+{
+ if ( language_is_set(LANG_OC)
+ && chunk_is_token(pc, CT_SPAREN_OPEN))
+ {
+ Chunk *prev = pc->GetPrevNcNnl();
+
+ if (chunk_is_token(prev, CT_FOR))
+ {
+ Chunk *next = pc;
+
+ while ( next != nullptr
+ && next->type != CT_SPAREN_CLOSE
+ && next->type != CT_IN)
+ {
+ next = next->GetNextNcNnl();
+ }
+
+ if (chunk_is_token(next, CT_IN))
+ {
+ return(true);
+ }
+ }
+ }
+ return(false);
+}
+
+
+/**
+ * Returns true if pc is an CT_ATTRIBUTE or CT_DECLSPEC
+ */
+bool chunk_is_attribute_or_declspec(Chunk *pc);
+
+
+/**
+ * Returns true if pc is one of CT_CLASS, CT_ENUM, CT_ENUM_CLASS, CT_STRUCT or CT_UNION
+ */
+bool chunk_is_class_enum_struct_union(Chunk *pc);
+
+
+/**
+ * Returns true if pc is a CT_CLASS or CT_STRUCT
+ */
+bool chunk_is_class_or_struct(Chunk *pc);
+
+
+/**
+ * Returns true if pc is one of CT_CLASS, CT_STRUCT or CT_UNION
+ */
+bool chunk_is_class_struct_union(Chunk *pc);
+
+
+/**
+ * Returns true if pc is a CT_ENUM or CT_ENUM_CLASS
+ */
+bool chunk_is_enum(Chunk *pc);
+
+
+void set_chunk_type_real(Chunk *pc, E_Token tt, const char *func, int line);
+
+
+void set_chunk_parent_real(Chunk *pc, E_Token tt, const char *func, int line);
+
+
+#define set_chunk_type(pc, tt) set_chunk_type_real((pc), (tt), __unqualified_func__, __LINE__)
+
+
+#define set_chunk_parent(pc, tt) set_chunk_parent_real((pc), (tt), __unqualified_func__, __LINE__)
+
+
+E_Token get_chunk_parent_type(Chunk *pc);
+
+
+void chunk_flags_set_real(Chunk *pc, pcf_flags_t clr_bits, pcf_flags_t set_bits);
+
+
+#define chunk_flags_upd(pc, cc, ss) chunk_flags_set_real((pc), (cc), (ss))
+
+
+#define chunk_flags_set(pc, ss) chunk_flags_set_real((pc), {}, (ss))
+
+
+#define chunk_flags_clr(pc, cc) chunk_flags_set_real((pc), (cc), {})
+
+
+void chunk_set_parent(Chunk *pc, Chunk *parent);
+
+
+E_Token get_type_of_the_parent(Chunk *pc);
+
+
+/**
+ * @brief compare the positions of two tokens in a file.
+ *
+ * The function compares the two positions of two tokens.
+ *
+ * @param A_token
+ * @param B_token
+ *
+ * @return returns an integer less than, equal to, or greater than zero
+ * if A_token is found, respectively, to be less/before than, to
+ * match, or be greater/after than B_token.
+ */
+int chunk_compare_position(const Chunk *A_token, const Chunk *B_token);
+
+
+#endif /* CHUNK_LIST_H_INCLUDED */