HeaderDoc::HashObject

Declared In:

Introduction

Stores C preprocessor hashes.

Discussion

Each instance of the HashObject class stores a CPP hash pair for use in handling trees of #if/#else/#elif/#endif statements.

The purpose of this module is not entirely obvious until you see an example. Consider the following code:

         #if BLAH
             #define function_1 function_2
         #else
             void function_1(int arg);
         #endif
         

Normally, with a C preprocessor, either the #if or #else side of this CPP directive is parsed, but not both.

With HeaderDoc's C preprocessor, most of the time, HeaderDoc cannot know which version to include. Thus, it errs on the side of completeness and includes both. (HeaderDoc does, however, include only one side if you pass a -D or -U flag on the command line or if you provide a HeaderDoc comment for a definition of BLAH earlier in the header or in any header that it includes.)

Thus, without this module, the macro definition inside the #if side would rewrite the code inside the #else side, causing it to be parsed as:

             void function_2(int arg);
         

This is clearly not correct. This module fixes that problem by allowing the entire set of currently known C preprocessor macros to be stored in a tree structure and later restored while parsing these #if/#else/#elif/#endif directives.

Whenever the parser encounters any C preprocessor directive that this code cares about, the parser calls its helper function cppHashMerge, where the control logic for this module actually appears.

If the parser encounters a #if directive, that function stores the current C preprocessor macro set in the current tree node, then calls cppHashNodeNewChild. This function creates a new, nested chain containing a single entry (the #if node).

If the parser encounters a #else, #elif, or #endif directive, that function similarly stores the C preprocessor macro set in the current node (in this case, the #if node).

Next, if the directive was a #else or #elif directive, it also calls cppHashNodeNewSibling to create a new sibling and cppHashNodeResetToParent to obtain the parent's C preprocessor macro set for restoration by the parser (effectively undoing the result of the #if clause).

If the directive was the closing #endif directive, after storing the macro set, the parser calls cppHashNodePop. This function pops the entire #if chain off the tree, then merges the macro sets from all of the chains together. The result is that the contents of the #if clause do not alter the contents of the #else clause, but become active upon reaching the terminating #endif clause. In cases of conflicting definitions of symbols, the first definition wins.



Member Functions

_initialize

Initializes an instance of a MinorAPIElement object.

cppHashNodeLastChild

Returns the last child of a CPP hash tree node.

cppHashNodeMergeHashes

Merges two C preprocessor macro sets, with precedence given to the first.

cppHashNodeNewChild

Creates a CPP hash tree node as a child of another node

cppHashNodeNewSibling

Creates a CPP hash tree node as a sibling of another node

cppHashNodePop

Pops a CPP hash node chain off the tree.

cppHashNodeResetToParent

Returns the C preprocessor macro set (hash and argument hash) from the parent of the specified node.

cppHashNodeSetHashes

Stores a copy of C preprocessor macro sets (hash and argument hash) into a HashObject node.

dbprint

Prints a CPP HashObject tree for debugging.

new

Creates a new HashObject object.


_initialize


Initializes an instance of a MinorAPIElement object.

Parameters
self

The object to initialize.


cppHashNodeLastChild


Returns the last child of a CPP hash tree node.

Parameters
self

The node whose child you are requesting.


cppHashNodeMergeHashes


Merges two C preprocessor macro sets, with precedence given to the first.

Parameters
hashref_1

A reference to the first CPP name hash.

arghashref_1

A reference to the first CPP argument hash.

hashref_2

A reference to the second CPP name hash.

arghashref_2

A reference to the second CPP argument hash.

Return Value

Returns an array containing a reference to the combined name hash and a reference to the combined argument hash.


cppHashNodeNewChild


Creates a CPP hash tree node as a child of another node

Parameters
self

The last node in the topmost chain.

debugname

A name used when printing the object for debugging.


cppHashNodeNewSibling


Creates a CPP hash tree node as a sibling of another node

Parameters
self

The last node in the topmost chain.

debugname

A name used when printing the object for debugging.


cppHashNodePop


Pops a CPP hash node chain off the tree.

Parameters
self

Any node in the topmost chain on the tree.

Discussion

This function is called at the end of a #if ... #else ... #elif ... #endif grouping. It pops the top chain off the tree, then returns the union of the #define declarations from each part of the group.

For example, if you have a #if, a #define, a #else, a #define, and a #endif, this pops the #if chain off of the tree and returns both of the two #define declarations if they do not conflict. If they conflict, it returns the first declaration encountered.


cppHashNodeResetToParent


Returns the C preprocessor macro set (hash and argument hash) from the parent of the specified node.

Parameters
self

The child of the node whose macro set you wish to obtain. This is usually the current node being manipulated.


cppHashNodeSetHashes


Stores a copy of C preprocessor macro sets (hash and argument hash) into a HashObject node.

Parameters
self

The node to modify.

cpphashref

The C preprocessor name hash to store.

cpparghashref

The C preprocessor argument hash to store.


dbprint


Prints a CPP HashObject tree for debugging.

sub dbprint 
Parameters
self

The tree to print.


new


Creates a new HashObject object.

sub new 
Parameters
param

A reference to the relevant package object (e.g. HeaderDoc::MinorAPIElement->new() to allocate a new instance of this class).


Member Data

CPPARGHASH

The CPP argument hash associated with this hash object.

CPPHASH

The CPP name hash associated with this hash object.

DEBUGNAME

A name for the hash object used for debugging purposes. This is set to the contents of the second parameter to cppHashNodeNewChild.

HeaderDoc::HashObject::VERSION

The revision control revision number for this module.


CPPARGHASH


The CPP argument hash associated with this hash object.

$self->{CPPARGHASH}

CPPHASH


The CPP name hash associated with this hash object.

$self->{CPPHASH}

DEBUGNAME


A name for the hash object used for debugging purposes. This is set to the contents of the second parameter to cppHashNodeNewChild.

$self->{DEBUGNAME}

HeaderDoc::HashObject::VERSION


The revision control revision number for this module.

$HeaderDoc::HashObject::VERSION = '$Revision: 1298084578 $';  
Discussion

In the git repository, contains the number of seconds since January 1, 1970.