Difference between revisions of "FpDebug-Watches-Intrinsic-Functions"

From Lazarus wiki
Jump to navigationJump to search
Line 1: Line 1:
 
= About =
 
= About =
  
[[LazDebuggerFp]] has some build in helper functions. They can be included in any watch using the pascal function calling syntax. The result is calculated internally be the debugger.
+
[[LazDebuggerFp]] has some build in helper functions and operators. They can be included in any watch using the pascal function calling syntax. The result is calculated internally be the debugger.
  
 
To avoid clashed with identifier names in the debugged target app, such intrinsic functions require a ":" prefix by default. E.g. ":length(s)".
 
To avoid clashed with identifier names in the debugged target app, such intrinsic functions require a ":" prefix by default. E.g. ":length(s)".
  
== Settings ==
+
= Intrinsic Operators =
 +
 
 +
== Array slice <i>MyArray[n..m]</i> with mapping ==
 +
 
 +
The array slice operator is available in freepascal, when calling a function that accepts an open array.
 +
 
 +
FpDebug extends this operator. The returned array slice can map any operation on its members. That is, if you do <i>MyArray[1..5]+4</i> then the <i>+4</i> will not act on the array slice, but instead on each entry in the slice.
 +
 
 +
This is true for any operation (including further index operations).
 +
* <i>MyArray[5..9]+1</i> Adds 1 to each array element
 +
* <i>TObjec(MyPointerArray[5..9])</i> type casts each array element
 +
* <i>MyRecordArray[5..9].Field</i> Show the field <i>.field</i> each array element
 +
* <i>MyMultiDimArray[5..9][2..4]</i> Selects a slice within each element of the outer slice
 +
* <i>MySingleDimArray[5..9][0]</i> Will not work. Since the array has only one dimension. It is not possible to select the element <i>[0]</i> from the slice. The operation is attempted on the elements of the slice.
 +
 
 +
== String slice <i>MyString[n..m]</i> ==
 +
 
 +
Select a substring.
 +
 
 +
Unlike the array-slice, this returns a single string and not an array of chars. Therefore any operation on the result will affect the single string, and not each char.
 +
 
 +
Similar to the intrinsic <i>SubStr</i>. For strings this is always limited to the bounds. <i>SubStr</i> can use "ForcePtr" to ignore bounds.
 +
 
 +
= Intrinsic Functions =
 +
 
 +
=== Settings ===
  
 
The prefix can be chosen or switched off. In the property grid of the debugger backend setup the option "IntrinsicPrefix" can be found.
 
The prefix can be chosen or switched off. In the property grid of the debugger backend setup the option "IntrinsicPrefix" can be found.
Line 21: Line 46:
 
</ul>
 
</ul>
  
= Length(String-or-array) =
+
== Length(String-or-array) ==
  
 
Returns the length of an array or string.
 
Returns the length of an array or string.
Line 28: Line 53:
  
  
= CC(instance) {ChildClass} =
+
== CC(instance) {ChildClass} ==
  
 
Type-casts an object (class instance) to the instantiated class type.
 
Type-casts an object (class instance) to the instantiated class type.
Line 48: Line 73:
 
":CC()" takes exactly one argument. If the argument is not an object, or can not be typecasted, then it is passed through. E.g. ":CC(1)" just return "1".
 
":CC()" takes exactly one argument. If the argument is not an object, or can not be typecasted, then it is passed through. E.g. ":CC(1)" just return "1".
  
= RefCnt(string-or-array) =
+
== RefCnt(string-or-array) ==
  
 
Get FPC's internal ref-count for LongString(AnsiString) or dynamic arrays.
 
Get FPC's internal ref-count for LongString(AnsiString) or dynamic arrays.
Line 54: Line 79:
 
Strings may work only with DWARF-3.
 
Strings may work only with DWARF-3.
  
= Pos(SubString, MainString [, CaseInsensitive=False]) =
+
== Pos(SubString, MainString [, CaseInsensitive=False]) ==
  
 
Works like the "Pos" function.
 
Works like the "Pos" function.
Line 60: Line 85:
 
Accepts an optional 3rd argument of boolean type. If True, both strings will be run through "LowerCase" to make it case insensitive. (May not work for utf-8)
 
Accepts an optional 3rd argument of boolean type. If True, both strings will be run through "LowerCase" to make it case insensitive. (May not work for utf-8)
  
= SubStr(Str, Start, Len [, ForcePtr=False]) =
+
== SubStr(Str, Start, Len [, ForcePtr=False]) ==
  
 
Similar to "copy()"
 
Similar to "copy()"

Revision as of 23:53, 12 March 2023

About

LazDebuggerFp has some build in helper functions and operators. They can be included in any watch using the pascal function calling syntax. The result is calculated internally be the debugger.

To avoid clashed with identifier names in the debugged target app, such intrinsic functions require a ":" prefix by default. E.g. ":length(s)".

Intrinsic Operators

Array slice MyArray[n..m] with mapping

The array slice operator is available in freepascal, when calling a function that accepts an open array.

FpDebug extends this operator. The returned array slice can map any operation on its members. That is, if you do MyArray[1..5]+4 then the +4 will not act on the array slice, but instead on each entry in the slice.

This is true for any operation (including further index operations).

  • MyArray[5..9]+1 Adds 1 to each array element
  • TObjec(MyPointerArray[5..9]) type casts each array element
  • MyRecordArray[5..9].Field Show the field .field each array element
  • MyMultiDimArray[5..9][2..4] Selects a slice within each element of the outer slice
  • MySingleDimArray[5..9][0] Will not work. Since the array has only one dimension. It is not possible to select the element [0] from the slice. The operation is attempted on the elements of the slice.

String slice MyString[n..m]

Select a substring.

Unlike the array-slice, this returns a single string and not an array of chars. Therefore any operation on the result will affect the single string, and not each char.

Similar to the intrinsic SubStr. For strings this is always limited to the bounds. SubStr can use "ForcePtr" to ignore bounds.

Intrinsic Functions

Settings

The prefix can be chosen or switched off. In the property grid of the debugger backend setup the option "IntrinsicPrefix" can be found.

  • ipColon
    Require a ":" as prefix
  • ipExclamation
    Require a "!" as prefix
  • ipNoPrefix
    Don't require a prefix.
    If function calling is enabled for the watch, the intrinsic takes precedence, and may hide a call-able function in the target app. (Use the & to bypass the intrinsic and trigger function eval. E.g.: "&length()")

Length(String-or-array)

Returns the length of an array or string.

See FpDebug#Strings_(vs_PChar_and_Array_of_Char) for info about string types in the debugger.


CC(instance) {ChildClass}

Type-casts an object (class instance) to the instantiated class type.


E.g. "Sender: TObject" is by default evaluated as TObject. ":CC(Sender)" will find the actual class of the instance and the result will be e.g. a TButton or TForm. ":CC(Sender)" is the same as either writing "TForm(Sender)" or "TButton(Sender)", but automatically adapts to the correct type.


Simply watching ":CC(Sender)" returns the same result as checking the "Use instance class" checkbox in the watches properties.

The difference between ":CC()" and "Use instance class" is

  • "Use instance class" will not allow you to write "Sender.FOwner"
  • The intrinsic can be used: ":CC(Sender).FOwner"
The "Use instance class" checkbox can then be used on the result of ":CC(Sender).FOwner"
  • ":CC()" can be nested: ":CC(:CC(Sender).FOwner).FHint"


":CC()" takes exactly one argument. If the argument is not an object, or can not be typecasted, then it is passed through. E.g. ":CC(1)" just return "1".

RefCnt(string-or-array)

Get FPC's internal ref-count for LongString(AnsiString) or dynamic arrays.

Strings may work only with DWARF-3.

Pos(SubString, MainString [, CaseInsensitive=False])

Works like the "Pos" function.

Accepts an optional 3rd argument of boolean type. If True, both strings will be run through "LowerCase" to make it case insensitive. (May not work for utf-8)

SubStr(Str, Start, Len [, ForcePtr=False])

Similar to "copy()"

Gets a substring.

  • Str: A String (Ansi or short) or pointer (pchar or other)
Note: the handling of String vs Pchar may depend on the Dwarf version and the debuggers ability to distinguish between PChar and String
Using Dwarf-2 a string may be seen as pchar instead
  • Start: A 1-based index, that must be 1 or greater (if the argument is a string and ForcePtr absent or false)
  • Len: Amount of chars to copy.
  • ForcePtr: Forces String to be handled the same as pointers


If acting on a string:

  • If "Start" is greater than the length of Str, the the result is empty
  • If "Start + Len" exceeds the length or Str, then the result will be cut at the end of Str.


If acting on Pointers or ForcePtr

  • "Start" is effectively 0-based. Start will be added to the address that the pointer points to.
"Start" can be negative.
  • "Len" will not be limited.
  • This means any memory around the pointers destination can be selected and returned as string.