diff options
Diffstat (limited to 'python/src/tcf/services/expressions.py')
-rw-r--r-- | python/src/tcf/services/expressions.py | 592 |
1 files changed, 395 insertions, 197 deletions
diff --git a/python/src/tcf/services/expressions.py b/python/src/tcf/services/expressions.py index 68c727ece..6d08cf1d0 100644 --- a/python/src/tcf/services/expressions.py +++ b/python/src/tcf/services/expressions.py @@ -9,30 +9,206 @@ # * Wind River Systems - initial API and implementation # ***************************************************************************** -""" -Expressions service allows TCF client to perform expression evaluation on +"""Expressions service allows TCF client to perform expression evaluation on remote target. + The service can be used to retrieve or modify values of variables or any data structures in remote target memory. + +Expressions Properties +---------------------- +Context Properties +^^^^^^^^^^^^^^^^^^ ++--------------------+--------------+-----------------------------------------+ +| Name | Type | Description | ++====================+==============+=========================================+ +| PROP_BITS | |int| | Size of expression value in bits. | ++--------------------+--------------+-----------------------------------------+ +| PROP_CAN_ASSIGN | |bool| | **True** if the expression can be | +| | | assigned a new value. | ++--------------------+--------------+-----------------------------------------+ +| PROP_CLASS | |basestring| | Expression type class. See | +| | | :class:`~tcf.services.symbols.TypeClass`| ++--------------------+--------------+-----------------------------------------+ +| PROP_EXPRESSION | |basestring| | Expression script. | ++--------------------+--------------+-----------------------------------------+ +| PROP_HAS_FUNC_CALL | |bool| | **True** if the expression contains | +| | | target function call. | ++--------------------+--------------+-----------------------------------------+ +| PROP_ID | |basestring| | Expression context ID. | ++--------------------+--------------+-----------------------------------------+ +| PROP_LANGUAGE | |basestring| | Language of expression script. | ++--------------------+--------------+-----------------------------------------+ +| PROP_PARENT_ID | |basestring| | ID of expression's parent context. | ++--------------------+--------------+-----------------------------------------+ +| PROP_SIZE | |int| | Size in bytes. | ++--------------------+--------------+-----------------------------------------+ +| PROP_SYMBOL_ID | |basestring| | Symbol ID if the expression represents a| +| | | symbol. | ++--------------------+--------------+-----------------------------------------+ +| PROP_TYPE | |basestring| | Expression type ID. | ++--------------------+--------------+-----------------------------------------+ + +Value Properties +^^^^^^^^^^^^^^^^ ++----------------+------------------------------------------------------------+ +| Name | Description | ++================+============================================================+ +| VAL_ADDRESS | If the value is located in target memory, the address of | +| | the value. | ++----------------+------------------------------------------------------------+ +| VAL_BIG_ENDIAN | Expression is big endian. | ++----------------+------------------------------------------------------------+ +| VAL_CLASS | Value type class. See | +| | :class:`~tcf.services.symbols.TypeClass`. | ++----------------+------------------------------------------------------------+ +| VAL_REGISTER | If the value is located in a register, the register ID | +| | that holds the value. | ++----------------+------------------------------------------------------------+ +| VAL_SYMBOL | If the value is defined by a symbol, the symbol ID. | ++----------------+------------------------------------------------------------+ +| VAL_TYPE | The symbol type ID of the value. | ++----------------+------------------------------------------------------------+ + +Service Methods +--------------- +.. autodata:: NAME +.. autoclass:: ExpressionsService + +addListener +^^^^^^^^^^^ +.. automethod:: ExpressionsService.addListener + +assign +^^^^^^ +.. automethod:: ExpressionsService.assign + +create +^^^^^^ +.. automethod:: ExpressionsService.create + +dispose +^^^^^^^ +.. automethod:: ExpressionsService.dispose + +evaluate +^^^^^^^^ +.. automethod:: ExpressionsService.evaluate + +getChildren +^^^^^^^^^^^ +.. automethod:: ExpressionsService.getChildren + +getContext +^^^^^^^^^^ +.. automethod:: ExpressionsService.getContext + +getName +^^^^^^^ +.. automethod:: ExpressionsService.getName + +removeListener +^^^^^^^^^^^^^^ +.. automethod:: ExpressionsService.removeListener + +Callback Classes +---------------- +DoneAssign +^^^^^^^^^^ +.. autoclass:: DoneAssign + :members: + +DoneCreate +^^^^^^^^^^ +.. autoclass:: DoneCreate + :members: + +DoneDispose +^^^^^^^^^^^ +.. autoclass:: DoneDispose + :members: + +DoneEvaluate +^^^^^^^^^^^^ +.. autoclass:: DoneEvaluate + :members: + +DoneGetChildren +^^^^^^^^^^^^^^^ +.. autoclass:: DoneGetChildren + :members: + +DoneGetContext +^^^^^^^^^^^^^^ +.. autoclass:: DoneGetContext + :members: + +Listener +-------- +.. autoclass:: ExpressionsListener + :members: + +Helper Classes +-------------- +Expression +^^^^^^^^^^ +.. autoclass:: Expression + :members: + +Value +^^^^^ +.. autoclass:: Value + :members: + """ from .. import services +from . import symbols -# Service name. NAME = "Expressions" +"""Expressions service name.""" + +# Expression context property names. + +PROP_ID = "ID" +PROP_PARENT_ID = "ParentID" +PROP_SYMBOL_ID = "SymbolID" +PROP_LANGUAGE = "Language" +PROP_EXPRESSION = "Expression" +PROP_BITS = "Bits" +PROP_SIZE = "Size" +PROP_TYPE = "Type" +PROP_CAN_ASSIGN = "CanAssign" +PROP_HAS_FUNC_CALL = "HasFuncCall" +PROP_CLASS = "Class" # same as symbols.TypeClass + +# Expression value property names. + +VAL_CLASS = "Class" # same as symbols.TypeClass +VAL_TYPE = "Type" +VAL_SYMBOL = "Symbol" +VAL_REGISTER = "Register" +VAL_ADDRESS = "Address" +VAL_BIG_ENDIAN = "BigEndian" class Expression(object): - """ - Expression object represent an expression that can be evaluated by remote - target. + """Expression object represent an expression that can be evaluated by + remote target. + It has a unique ID and contains all information necessary to compute a value. + The object data usually includes: - 1. process, thread or stack frame ID that should be used to resolve - symbol names - 2. a script that can compute a value, like "x.y + z" + + 1. process, thread or stack frame ID that should be used to resolve + symbol names + 2. a script that can compute a value, like ``x.y + z`` + + :param props: Property dictionnary defining the expression. + See `Context Properties`_. """ + def __init__(self, props): self._props = props or {} @@ -40,108 +216,114 @@ class Expression(object): return "[Expression Context %s]" % self._props def getID(self): - """ - Get context ID. - @return context ID. + """Get context ID. + + :returns: Context ID. """ return self._props.get(PROP_ID) def getParentID(self): - """ - Get parent context ID. - @return parent context ID. + """Get parent context ID. + + :returns: Parent context ID. """ return self._props.get(PROP_PARENT_ID) def getLanguage(self): - """ - Get expression script language ID. - @return language ID. + """Get expression script language ID. + + :returns: Language ID. """ return self._props.get(PROP_LANGUAGE) def getExpression(self): - """ - Return expression string - the script part of the context. - @return expression script string + """Return expression string - the script part of the context. + + :returns: Expression script string. """ return self._props.get(PROP_EXPRESSION) def getSymbolID(self): - """ - Return symbol ID if the expression represents a symbol (e.g. local + """Return symbol ID if the expression represents a symbol (e.g. local variable). - @return symbol ID + + :returns: Symbol ID. """ return self._props.get(PROP_SYMBOL_ID) def getBits(self): - """ - Get size of expression value in bits. - Can be 0 if value size is even number of bytes, use getSize() in such - case. - @return size in bits. + """Get size of expression value in bits. + + Can be **0** if value size is even number of bytes, use :meth:`getSize` + in such case. + + :returns: Size in bits. """ return self._props.get(PROP_BITS, 0) def getSize(self): - """ - Get size in bytes. The size can include extra (unused) bits. - This is "static" or "declared" size - as determined by expression type. - @return size in bytes. + """Get size in bytes. The size can include extra (unused) bits. + + This is *static* or *declared* size - as determined by expression type. + + :returns: Size in bytes. """ return self._props.get(PROP_SIZE, 0) - def getTypeID(self): + def getTypeClass(self): + """Get expression type class. + + :returns: type class + + .. seealso: :class:`~tcf.services.symbols.TypeClass` """ - Get expression type ID. Symbols service can be used to get type + return self._props.get(PROP_CLASS, symbols.TypeClass.unknown) + + def getTypeID(self): + """Get expression type ID. Symbols service can be used to get type properties. - This is "static" or "declared" type ID, actual type of a value can be + + This is *static* or *declared* type ID, actual type of a value can be different - if expression language supports dynamic typing. - @return type ID. + + :returns: Type ID. + + .. seealso:: :mod:`~tcf.services.symbols` """ return self._props.get(PROP_TYPE) def canAssign(self): - """ - Check if the expression can be assigned a new value. - @return true if can assign. + """Check if the expression can be assigned a new value. + + :returns: **True** if can assign. """ return self._props.get(PROP_CAN_ASSIGN) def hasFuncCall(self): - """ - Check if the expression contains target function call. + """Check if the expression contains target function call. + Such expression can resume the target when evaluated. - @return true if has a function call. + + :returns: **True** if has a function call. """ return (self._props.get(PROP_HAS_FUNC_CALL)) def getProperties(self): - """ - Get complete map of context properties. - @return map of context properties. + """Get complete dictionary of context properties. + + :returns: A |dict| of context properties. """ return self._props -# Expression context property names. -PROP_ID = "ID" -PROP_PARENT_ID = "ParentID" -PROP_SYMBOL_ID = "SymbolID" -PROP_LANGUAGE = "Language" -PROP_EXPRESSION = "Expression" -PROP_BITS = "Bits" -PROP_SIZE = "Size" -PROP_TYPE = "Type" -PROP_CAN_ASSIGN = "CanAssign" -PROP_HAS_FUNC_CALL = "HasFuncCall" - class Value(object): - """ - Value represents result of expression evaluation. + """Value represents result of expression evaluation. + Note that same expression can be evaluated multiple times with different results. + + :param value: Expression value. + :param props: Property dictionary defining the value. """ def __init__(self, value, props): @@ -152,93 +334,97 @@ class Value(object): return "[Expression Value %s %s]" % (self._value, self._props) def getTypeClass(self): + """Get value type class. + + :returns: type class + + .. seealso: :class:`~tcf.services.symbols.TypeClass` """ - Get value type class. - @see symbols.TypeClass - @return type class - """ - return self._props.get(VAL_CLASS, 0) + return self._props.get(VAL_CLASS, symbols.TypeClass.unknown) def getTypeID(self): - """ - Get value type ID. Symbols service can be used to get type properties. - @return type ID. + """Get value type ID. Symbols service can be used to get type + properties. + + :returns: Type ID. """ return self._props.get(VAL_TYPE) def isBigEndian(self): - """ - Check endianness of the values. + """Check endianness of the values. + Big-endian means decreasing numeric significance with increasing byte number. - @return true if big-endian. + + :returns: **True** if big-endian. """ - return self._props.get(VAL_BIG_ENDIAN) + return self._props.get(VAL_BIG_ENDIAN, False) def getAddress(self): - """ - Get the value address if one exists. - @return The value address or None if none address exists for the value + """Get the value address if one exists. + + :returns: The value address or **None** if none address exists for the + value. """ return self._props.get(VAL_ADDRESS) def getRegisterID(self): - """ - Return register ID if the value represents register variable. - @return register ID or None. + """Return register ID if the value represents register variable. + + :returns: Register ID or **None**. """ return self._props.get(VAL_REGISTER) def getSymbolID(self): - """ - Return symbol ID if the value represents a symbol. - @return symbol ID or None. + """Return symbol ID if the value represents a symbol. + + :returns: Symbol ID or **None** if value is not a symbol. """ return self._props.get(VAL_SYMBOL) def getValue(self): - """ - Get value as array of bytes. - @return value as array of bytes. + """Get a 'packed binary data' encoded value. + + :returns: value as 'packed binary data'. + + .. seealso:: :mod:`struct` """ return self._value def getProperties(self): - """ - Get complete map of value properties. - @return map of value properties. + """Get complete dictionary of value properties. + + :returns: A |dict| of value properties. """ return self._props -# Expression value property names. -VAL_CLASS = "Class" -VAL_TYPE = "Type" -VAL_SYMBOL = "Symbol" -VAL_REGISTER = "Register" -VAL_ADDRESS = "Address" -VAL_BIG_ENDIAN = "BigEndian" - class ExpressionsService(services.Service): - def getName(self): + """Get this service name. + + :returns: The value of string :const:`NAME` + """ return NAME def getContext(self, contextID, done): - """ - Retrieve expression context info for given context ID. - @see Expression + """Retrieve expression context info for given context ID. + + :param contextID: Context ID. + :param done: Call back interface called when operation is completed. + :type done: :class:`DoneGetContext` - @param contextID - context ID. - @param done - call back interface called when operation is completed. - @return - pending command handle. + :returns: pending command handle. + + .. seealso:: :class:`Expression` """ raise NotImplementedError("Abstract method") def getChildren(self, parent_context_id, done): - """ - Retrieve children IDs for given parent ID. + """Retrieve children IDs for given parent ID. + Meaning of the operation depends on parent kind: + 1. expression with type of a struct, union, or class - fields 2. expression with type of an enumeration - enumerators 3. expression with type of an array - array elements @@ -249,170 +435,182 @@ class ExpressionsService(services.Service): Children list *does not* include IDs of expressions that were created by clients using "create" command. - @param parent_context_id - parent context ID. - @param done - call back interface called when operation is completed. - @return - pending command handle. + :param parent_context_id: parent context ID. + :param done: call back interface called when operation is completed. + :type done: :class:`DoneGetChildren` + + :returns: Pending command handle. """ raise NotImplementedError("Abstract method") def create(self, parent_id, language, expression, done): - """ - Create an expression context. + """Create an expression context. + The context should be disposed after use. - @param parent_id - a context ID that can be used to resolve symbol - names. - @param language - language of expression script, None means default - language - @param expression - expression script - @param done - call back interface called when operation is completed. - @return - pending command handle. + + :param parent_id: A context ID that can be used to resolve symbol + names. + :param language: Language of expression script, **None** means default + language. + :param expression: Expression script + :param done: Call back interface called when operation is completed. + :type done: :class:`DoneCreate` + + :returns: pending command handle. """ raise NotImplementedError("Abstract method") def dispose(self, contextID, done): - """ - Dispose an expression context that was created by create() - @param contextID - the expression context ID - @param done - call back interface called when operation is completed. - @return - pending command handle. + """Dispose an expression context that was created by + :meth:`~ExpressionsService.create` + + :param contextID: The expression context ID. + :param done: Call back interface called when operation is completed. + :type done: :class:`DoneDispose` + + :returns: Pending command handle. """ raise NotImplementedError("Abstract method") def evaluate(self, contextID, done): - """ - Evaluate value of an expression context. - @param contextID - the expression context ID - @param done - call back interface called when operation is completed. - @return - pending command handle. + """Evaluate value of an expression context. + + :param contextID: The expression context ID + :param done: Call back interface called when operation is completed. + :type done: :class:`DoneEvaluate` + + :returns: Pending command handle. """ raise NotImplementedError("Abstract method") def assign(self, contextID, value, done): - """ - Assign a value to memory location determined by an expression. - @param contextID - expression ID. - @param value - value as an array of bytes. - @param done - call back interface called when operation is completed. - @return - pending command handle. + """Assign a value to memory location determined by an expression. + + :param contextID: Expression ID. + :param value: Value as an array of bytes. + :param done: Call back interface called when operation is completed. + :type done: :class:`DoneAssign` + + :returns: pending command handle. """ raise NotImplementedError("Abstract method") def addListener(self, listener): - """ - Add expressions service event listener. - @param listener - event listener implementation. + """Add expressions service event listener. + + :param listener: Event listener implementation. + :type listener: :class:`ExpressionsListener` """ raise NotImplementedError("Abstract method") def removeListener(self, listener): - """ - Remove expressions service event listener. - @param listener - event listener implementation. + """Remove expressions service event listener. + + :param listener: Event listener implementation. + :type listener: :class:`ExpressionsListener` """ raise NotImplementedError("Abstract method") class DoneGetContext(object): - """ - Client call back interface for getContext(). + """Client call back interface for :meth:`~ExpressionsService.getContext`. """ def doneGetContext(self, token, error, context): - """ - Called when context data retrieval is done. - @param token - command handle - @param error - error description if operation failed, None if - succeeded. - @param context - context properties. + """Called when context data retrieval is done. + + :param token: Command handle. + :param error: Error description if operation failed, **None** if + succeeded. + :param context: Context properties. """ pass class DoneGetChildren(object): - """ - Client call back interface for getChildren(). + """Client call back interface for :meth:`~ExpressionsService.getChildren`. """ def doneGetChildren(self, token, error, context_ids): - """ - Called when context list retrieval is done. - @param token - command handle - @param error - error description if operation failed, None if - succeeded. - @param context_ids - array of available context IDs. + """Called when context list retrieval is done. + + :param token: Command handle. + :param error: Error description if operation failed, **None** if + succeeded. + :param context_ids: An iterable of available context IDs. """ pass class DoneCreate(object): - """ - Client call back interface for create(). + """Client call back interface for :meth:`~ExpressionsService.create`. """ def doneCreate(self, token, error, context): - """ - Called when context create context command is done. - @param token - command handle - @param error - error description if operation failed, None if - succeeded. - @param context - context properties. + """Called when context create context command is done. + + :param token: Command handle. + :param error: Error description if operation failed, **None** if + succeeded. + :param context: Context properties. """ pass class DoneDispose(object): - """ - Client call back interface for dispose(). - """ + """Client call back interface for :meth:`~ExpressionsService.dispose`.""" + def doneDispose(self, token, error): - """ - Called when context dispose command is done. - @param token - command handle - @param error - error description if operation failed, None if - succeeded. + """Called when context dispose command is done. + + :param token: Command handle. + :param error: Error description if operation failed, **None** if + succeeded. """ pass class DoneEvaluate(object): - """ - Client call back interface for evaluate(). - """ + """Client call back interface for :meth:`~ExpressionsService.evaluate`.""" + def doneEvaluate(self, token, error, value): - """ - Called when context dispose command is done. - @param token - command handle - @param error - error description if operation failed, None if - succeeded. - @param value - expression evaluation result + """Called when context dispose command is done. + + :param token: Command handle. + :param error: Error description if operation failed, None if + succeeded. + :param value: Expression evaluation result. See :class:`Value`. """ pass class DoneAssign(object): - """ - Client call back interface for assign(). - """ + """Client call back interface for :meth:`~ExpressionsService.assign`.""" + def doneAssign(self, token, error): - """ - Called when assign command is done. - @param token - command handle - @param error - error description if operation failed, None if - succeeded. + """Called when assign command is done. + + :param token: Command handle + :param error: Error description if operation failed, **None** if + succeeded. """ pass class ExpressionsListener(object): - """ - Registers event listener is notified when registers context hierarchy + """Registers event listener is notified when registers context hierarchy changes, and when a register is modified by the service commands. """ + def valueChanged(self, contextID): - """ - Called when expression value was changed and clients - need to update themselves. Clients, at least, should invalidate - corresponding cached expression data. - Not every change is notified - it is not possible, - only those, which are not caused by normal execution of the debuggee. - At least, changes caused by "assign" command should be notified. - @param contextID - expression context ID. + """Called when expression value was changed and clients need to update + themselves. + + Clients, at least, should invalidate corresponding cached expression + data. + + .. note:: Not every change is notified - it is not possible, only those + which are not caused by normal execution of the debuggee. At + least, changes caused by :meth:`~ExpressionsService.assign` + command should be notified. + + :param contextID: Expression context ID. """ pass |