More fun with labelling breakpoints

Back in my first Debugger tips post I provided some macros that allow you to tag a set of breakpoints with a string so that they can easily be enabled or disabled from the command window.  Well, just for kicks, I decided to expand on that notion a bit and made a set of new macros that can not only do that, but also support multiple labels (the new name for tags) for breakpoints and tracepoints.

Following this description you'll find the source for these macros.  Basically, you can use the instructions provided Idiot's Guide to Creating and Using VS Macros to add these macros to your installation.  After you do that, just run the SetupBPLabels macro, and you'll be able to use the following commands in the command window:

  • labelbps - Allows you to add a new label to the current set of enabled breakpoints or tracepoints.  If a label is not provided "label" is used by default.
  • enablebps - Allows you to enable all breakpoints that are associated with the supplied label.  If * is provided as the target label or then all breakpoints are enabled regardless of their label.  If no label is provided then any breakpoint without a label will be enabled.
  • disablebps - Allows you to disable all breakpoints that are associated with the supplied label.  If * is provided as the target label then all breakpoints are disabled regardless of their label.  If no label is provided then any breakpoint without a label will be disabled.
  • clearlabel - Allows you to remove a label from your set of breakpoints.  If * is provided as the target label, then all labels are cleared.  When a label is cleared, it no longer exists, so be careful here.
  • listbps - Lists the breakpoints associated with the supplied label.  If no label is supplied, then all breakpoints are listed along with their labels.

I'm not really sure how useful this set of macros will be for you, but it was fun writing them!  Let me know what you think, or if you think there's some improvements that could be made to make them even more useful!  Please note that I am not much of a VB programmer, so if you have suggestions as to how to improve the code, I'm all ears!

    ' -------------------------------------------------------------------------

    Sub SetupBPLabels()

        DTE.ExecuteCommand("alias enablebps Macros.MyMacros.BPLabels.EnableBPs")

        DTE.ExecuteCommand("alias disablebps Macros.MyMacros.BPLabels.DisableBPs")

        DTE.ExecuteCommand("alias listbps Macros.MyMacros.BPLabels.ListBPs")

        DTE.ExecuteCommand("alias labelbps Macros.MyMacros.BPLabels.LabelEnabledBPs")

        DTE.ExecuteCommand("alias clearlabel Macros.MyMacros.BPLabels.ClearBPLabel")

    End Sub

 

   ' -------------------------------------------------------------------------

   Sub LabelEnabledBPs(Optional ByRef strLabel As String = "label")

        Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

        If (bps.Count > 0) Then

            For Each bp As EnvDTE.Breakpoint In bps

                Dim strCurLabels As String = GetBPLabels(bp)

                If (bp.Enabled = True And Not BPLabeledAs(bp, strLabel)) Then

                    If (strCurLabels.Length > 0) Then

                        strCurLabels += ";"

                    End If

                    strCurLabels = strCurLabels + strLabel

                    SetBPLabels(bp, strCurLabels)

                End If

            Next

        Else

            System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to label")

        End If

    End Sub

 

    ' -------------------------------------------------------------------------

    Sub ClearBPLabel(Optional ByRef strBadLabel As String = "")

        Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

        If (bps.Count > 0) Then

            For Each bp As EnvDTE.Breakpoint In bps

                Dim strCurLabels As String = GetBPLabels(bp)

                SetBPLabels(bp, "")

                If (strBadLabel <> "*") Then

                    Dim labels() As String = strCurLabels.Split(";")

                    Dim strNewLabels As String = ""

                    For Each s As String In labels

                        If (s.ToLower <> strBadLabel.ToLower) Then

                            If (strNewLabels.Length > 0) Then

                                strNewLabels += ";"

                            End If

                            strNewLabels = strNewLabels + s

                        End If

                    Next

                    SetBPLabels(bp, strNewLabels)

                End If

            Next

        Else

            System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to label")

        End If

    End Sub

 

    ' -------------------------------------------------------------------------

    Sub EnableBPs(Optional ByRef strLabel As String = "")

        Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

        If (bps.Count > 0) Then

            For Each bp As EnvDTE.Breakpoint In bps

                If (strLabel = "*" Or BPLabeledAs(bp, strLabel) Or (GetBPLabels(bp).Length = 0 And strLabel.Length = 0)) Then

                    bp.Enabled = True

                End If

            Next

        Else

            System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to enable")

        End If

    End Sub

 

    ' -------------------------------------------------------------------------

    Sub DisableBPs(Optional ByRef strLabel As String = "")

        Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

        If (bps.Count > 0) Then

            For Each bp As EnvDTE.Breakpoint In bps

                If (strLabel = "*" Or BPLabeledAs(bp, strLabel) Or (GetBPLabels(bp).Length = 0 And strLabel.Length = 0)) Then

                    bp.Enabled = False

                End If

            Next

        Else

            System.Windows.Forms.MessageBox.Show("Can't find any breakpoints to enable")

        End If

 

    End Sub

 

    ' -------------------------------------------------------------------------

    Sub ListBPs(Optional ByRef strLabel As String = "")

        Dim bps As EnvDTE.Breakpoints = DTE.Debugger.Breakpoints

        Dim outpane As EnvDTE.CommandWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindCommandWindow).Object

 

        Dim i As Integer = 1

        For Each bp As EnvDTE.Breakpoint In bps

            If (strLabel.Length = 0 Or BPLabeledAs(bp, strLabel)) Then

                Dim strEnabled As String = ""

                If bp.Enabled Then

                    strEnabled = "x"

                End If

 

                outpane.OutputString("BP #" + i.ToString() + " " + strEnabled + vbTab + "Name: " + bp.Name + vbCrLf)

 

                If (strLabel.Length = 0) Then

                    outpane.OutputString(vbTab + vbTab + "Labels: " + GetBPLabels(bp) + vbCrLf)

                End If

            End If

            i = i + 1

        Next

    End Sub

 

    ' -------------------------------------------------------------------------

    Private Function GetBPLabels(ByRef bp As EnvDTE.Breakpoint) As String

        Dim strStartTag As String = "<labels>"

        Dim strEndTag As String = "</labels>"

        Dim ndxStart As Integer = bp.Tag.IndexOf(strStartTag) + strStartTag.Length

        Dim ndxEnd As Integer = bp.Tag.IndexOf(strEndTag)

        If (ndxStart > 0 And ndxEnd > ndxStart) Then

            GetBPLabels = bp.Tag.Substring(ndxStart, ndxEnd - ndxStart)

        Else

            GetBPLabels = ""

        End If

    End Function

 

    ' -------------------------------------------------------------------------

    Private Sub SetBPLabels(ByRef bp As EnvDTE.Breakpoint, ByRef labels As String)

        bp.Tag = "<labels>" + labels + "</labels>"

    End Sub

 

    ' -------------------------------------------------------------------------

    Private Function BPLabeledAs(ByRef bp As EnvDTE.Breakpoint, ByRef strLabel As String) As Boolean

        Dim bLabelFound As Boolean = False

 

        If (strLabel.Length > 0) Then

            Dim strLabels = GetBPLabels(bp)

            Dim labels() As String = strLabels.Split(";")

            For i As Integer = 0 To labels.Length - 1 And bLabelFound = False

                If (labels(i).ToLower = strLabel.ToLower) Then

                    bLabelFound = True

                End If

            Next

        End If

 

        Return bLabelFound

    End Function