MacroEnv¶
This an environment of macro declarations
It implements ISO/IEC 9899:1999(E) section 6 (aka ‘C’) and ISO/IEC 14882:1998(E) section 16 (aka ‘C++’)
-
exception
cpip.core.MacroEnv.
ExceptionMacroEnv
¶ Exception when handling MacroEnv object.
-
exception
cpip.core.MacroEnv.
ExceptionMacroEnvInvalidRedefinition
¶ Exception for a invalid redefinition of a macro. NOTE: Under C rules (C Rationale 6.10.3) callers should merely issue a suitable diagnostic.
-
exception
cpip.core.MacroEnv.
ExceptionMacroEnvNoMacroDefined
¶ Exception when trying to access a PpDefine that is not currently defined.
-
exception
cpip.core.MacroEnv.
ExceptionMacroIndexError
¶ Exception when an access to a PpDefine that generates a IndexError.
-
exception
cpip.core.MacroEnv.
ExceptionMacroReplacementInit
¶ Exception in the constructor.
-
exception
cpip.core.MacroEnv.
ExceptionMacroReplacementPredefinedRedefintion
¶ Exception for a redefinition of a macro id that is predefined.
-
class
cpip.core.MacroEnv.
MacroEnv
(enableTrace=False, stdPredefMacros=None)¶ Represents a set of #define directives that represent a macro processing environment. This provides support for #define and #undef directives. It also provides support for macro replacement see: ISO/IEC 9899:1999 (E) 6.10.3 Macro replacement.
- enableTrace
- Allows calls to
_debugTokenStream()
that may or may not produce log output (depending on logging level). If True this makes this code run slower, typically 3x slower - stdPredefMacros
If present should be a dictionary of:
{identifier : replacement_string_\n_terminated, ...}
For example:{ '__DATE__' : 'First of June\n', '__TIME__' : 'Just before lunchtime.\n', }
Each identifier must be in
STD_PREDEFINED_NAMES
-
_MacroEnv__define
(ppD)¶ Takes a
cpip.core.PpDefine.PpDefine
object and adds it to the map of objects. Does not check if it is a redefinition of a predefined macro. Does check if it is a valid redefinition.On success it returns the identifier of the macro.
The insertion is stable i.e. a valid re-definition does not replace the existing definition so that the definition file, line and reference count are preserved.
Parameters: ppD ( cpip.core.PpDefine.PpDefine
) – Macro definition.Returns: str
– Macro identifier.
-
_MacroEnv__setString
(theStr)¶ Takes a string
'identifier replacement\n'
and sets the macro map. This uses__define()
so only a redefinition exception is raised.Parameters: theStr ( str
) – Replacement string.Returns: NoneType
-
__init__
(enableTrace=False, stdPredefMacros=None)¶ Constructor.
A ‘reference’ is defined as: replacement or if defined. So:
- Count set to zero on
define()
- Increment on:
Parameters: - enableTrace (
bool
) – If True allows calls to_debugTokenStream()
that may or may not produce log output (depending on logging level). - stdPredefMacros (
dict({str : [str]})
) –If present should be a dictionary of:
{identifier : replacement_string_\n_terminated, ...}
These identifiers are not permitted to be redefined.
This also increments the count is the number of times that the identifier has been referenced in the lifetime of me.
Returns: NoneType
- Count set to zero on
-
__weakref__
¶ list of weak references to the object (if defined)
-
_assertDefineMapIntegrity
()¶ Returns True if dynamic tests on self._defineMap and self._expandedSet pass. i.e. every entry in self._expandedSet must be in self._defineMap.keys().
Returns: bool
– False on failure.
-
_debugTokenStream
(thePrefix, theArg='')¶ Writes to logging.debug() an interpretation of the token stream provided by theList. It will be preceded by the debugMarker value (if set) and that will always be cleared.
-
_expand
(theTtt, theGen, theFileLineCol)¶ Recursive call to expand macro symbols.
- theFileLineCol
- Is a
FileLocation.FileLineCol object
.
-
_hasExpanded
(theTtt)¶ Returns True if theTok represents a macro name that has already been expanded.
-
_reset
()¶ Initialises the dynamic values.
Returns: NoneType
-
_staticMacroDependencies
(theIdentifier)¶ Returns the immediate dependencies as a list of strings for a macro identified by the string.
Parameters: theIdentifier ( str
) – Macro name.Returns: list([]),list([str])
– List of macro names.
-
allStaticMacroDependencies
()¶ Returns a DuplexAdjacencyList() of macro dependencies for the Macro environment. All objects in the
cpip.util.Tree.DuplexAdjacencyList
are macro identifiers as strings.A
cpip.util.Tree.DuplexAdjacencyList
can be converted to acpip.util.Tree.Tree
and that can be converted to acpip.util.DictTree.DictTree
Returns: cpip.util.Tree.DuplexAdjacencyList
– The dependencies.
-
clear
()¶ Clears the macro environment.
-
define
(theGen, theFile, theLine)¶ Defines a macro. theGen should be in the state immediately after the
#define
i.e. this will consume leading whitespace and the trailing newline.Will raise a
ExceptionMacroEnvInvalidRedefinition
if the redefinition is not valid. May raise aPpDefine.ExceptionCpipDefineInit
(or sub class) on failure.On success it returns the identifier of the macro as a string.. The insertion is stable i.e. a valid re-definition does not replace the existing definition so that the existing state of the macro definition (file, line, reference count etc. are preserved.
Parameters: - theGen (
generator
) – Token generator. - theFile (
str
) – File identifier such as the path. - theLine (
int
) – Line number.
Returns: str
– Macro name.- theGen (
-
defined
(theTtt, flagInvert, theFileLineCol=None)¶ If the PpToken theTtt is an identifier that is currently defined then this returns 1 as a PpToken, 0 as a PpToken otherwise. If the macro exists in the environment its reference count is incremented.
- theFileLineCol
- Is a
FileLocation.FileLineCol object
.
See: ISO/IEC 9899:1999 (E) 6.10.1.
Parameters: - theTtt (
cpip.core.PpToken.PpToken
) – The token. - flagInvert (
bool
) – Invert the test. - theFileLineCol (
cpip.core.FileLocation.FileLineCol([str, int, int])
) – File location.
Returns: cpip.core.PpToken.PpToken
– A token that is either 0 or 1.Raises: KeyError
-
genMacros
(theIdentifier=None)¶ Generates PpDefine objects encountered during my existence. Macros that have been undefined will be generated first in order of un-definition followed by the currently defined macros in identifier order.
Macros that have been #undef’d will have the attribute isCurrentlyDefined as False.
-
genMacrosInScope
(theIdent=None)¶ Generates PpDefine objects encountered during my existence and still in scope i.e. not yet un-defined.
If theIdent is not None then only that named macros will be yielded.
Parameters: theIdent ( NoneType
) – Optionally the macro name.Returns: cpip.core.PpDefine.PpDefine
– Yields macro definitions.
-
genMacrosOutOfScope
(theIdent=None)¶ Generates PpDefine objects encountered during my existence but then undefined in the order of un-definition.
If theIdent is not None then only that named macros will be yielded.
Parameters: theIdent ( NoneType
) – Optionally the macro name.Returns: cpip.core.PpDefine.PpDefine
– Yields macro definitions.
-
getUndefMacro
(theIdx)¶ Returns the PpDefine object from the undef list for the given index. Will raise an
ExceptionMacroIndexError
if the index is out of range.
-
hasMacro
(theIdentifier)¶ Returns True if the environment has the macro.
Note
This does not increment the reference count so should not be used when processing
#ifdef
...,#if defined
... or#if !defined
... for those useisDefined()
anddefined()
instead.Parameters: theIdentifier ( str
) – Macro name.Returns: bool
– True if the macro is currently defined.
-
isDefined
(theTtt, theFileLineCol=None)¶ Returns True theTtt is an identifier that is currently defined, False otherwise. If True this increments the macro reference.
- theFileLineCol
- Is a
FileLocation.FileLineCol object
.
See: ISO/IEC 9899:1999 (E) 6.10.1.
-
macro
(theIdentifier)¶ Returns the macro identified by the identifier. Will raise a
ExceptionMacroEnvNoMacroDefined
is undefined.Parameters: theIdentifier ( str
) – Macro name.Returns: cpip.core.PpDefine.PpDefine
– The macro.
-
macroHistory
(incEnv=True, onlyRef=True)¶ Returns the macro history as a multi-line string
-
macroHistoryMap
()¶ Returns a map of
{ident : ([ints, ...], True/False), ...}
Where the macro identifier is mapped to a pair where: pair[0] is a list of indexes intogetUndefMacro()
. pair[1] is boolean, True if the identifier is currently defined i.e. it is the value ofself.hasMacro(ident). The macro can be obtained by self.macro().
-
macroNotDefinedDependencies
()¶ Returns a map of
{identifier : [class FileLineColumn, ...], ...}
where there has been an#ifdef
and nothing is defined. Thus these macros, if present, could alter the outcome i.e. it is dependency on them NOT being defined.
-
macroNotDefinedDependencyNames
()¶ Returns an unsorted list of identifies where there has been an
#ifdef
and nothing is defined. Thus these macros, if present, could alter the outcome i.e. it is dependency on them NOT being defined.Returns: list([str])
– List of macro names.
-
macroNotDefinedDependencyReferences
(theIdentifier)¶ Returns an ordered list of
cpip.core.FileLocation.FileLineCol`for an identifier where there has been an ``#ifdef`
and nothing is defined. Thus these macros, if present, could alter the outcome i.e. it is dependency on them NOT being defined.Parameters: theIdentifier ( str
) – Macro name.Returns: list([cpip.core.FileLocation.FileLineCol([str, int, int])])
– List of locations.
-
macros
()¶ Returns and unsorted list of strings of current macro identifiers.
Returns: list([str])
– Macro names.
-
mightReplace
(theTtt)¶ Returns True if theTok might be able to be expanded. ‘Might’ is not ‘can’ or ‘will’ because of this:
#define FUNC(a,b) a-b FUNC FUNC(45,3)
Becomes:
FUNC 45 -3
Thus
mightReplace('FUNC', ...)
is True in both cases but actual replacement only occurs once for the secondFUNC
.Parameters: theTtt ( cpip.core.PpToken.PpToken
) – The token.Returns: bool
– True if this might be replaceable.
-
referencedMacroIdentifiers
(sortedByRefcount=False)¶ Returns an unsorted list of macro identifiers that have a reference count > 0. If sortedByRefcount is True the list will be in increasing order of reference count then by name. Use reverse() on the result to get decreasing order. If sortedByRefcount is False the return value is unsorted.
-
replace
(theTtt, theGen, theFileLineCol=None)¶ Given a PpToken this returns the replacement as a list of
[class PpToken, ...]
that is the result of the substitution of macro definitions.- theGen
- Is a generator that might be used in the case of function-like macros to consume their argument lists.
- theFileLineCol
- Is a
FileLocation.FileLineCol object
.
-
set__FILE__
(theStr)¶ This sets the
__FILE__
macro directly.
-
set__LINE__
(theStr)¶ This sets the
__LINE__
macro directly.
-
undef
(theGen, theFile, theLine)¶ Removes a definition from the map and adds the PpDefine to self._undefS. It returns None. If no definition exists this has no side-effects on the internal representation.