Jump to content

Using StringRegExpReplace to update line numbers


benners
 Share

Recommended Posts

I have a few functions that I manually add line numbers to when I am writing them. As I move code around or improve it in the UDFs these numbers become out of sequence. I have written a function that scans UDFs , looks for certain function names and changes the line to represent the new line it is on.

Obviously there is a potential to totally hose the code. With this in mind I backup the files before running the updating function.  

My question is, can the StringRegExp patterns be improved to make it as bulletproof as possible.

#include <file.au3>

; replacing line number 133 with new line number 25
; the line could change but the line numbers (133 for example) are always in the same layout, as with $i_LineNumber =
; or function parameters, as with __Msi_ErrorSetValues and _Log_ErrorRoute

Local $s_Line = "Local $i_LineNumber = 133 ; some comment"
Local $i_NewNumber = 25
$s_Line = StringReplace($s_Line, StringRegExpReplace($s_Line, "(?i)(?:^.*= )(\d{1,})(?:.*)", '$1'), $i_NewNumber)
MsgBox(0, '$i_LineNumber', $s_Line)

$s_Line = "__Msi_ErrorSetValues(133, '$o_Records.StringData[2]') ; update variables for future COM errors"
$s_Line = StringReplace($s_Line, StringRegExpReplace($s_Line, "(?:^.*\()(-?\d{1,})(?:.*)", '$1'), $i_NewNumber)
MsgBox(0, '__Msi_ErrorSetValues', $s_Line)

$s_Line = "_Log_ErrorRoute('update', 'MSI', 133, '__Msi_ViewClose', '$o_View (' & IsObj($o_View) & ')')"
$s_Line = StringReplace($s_Line, StringRegExpReplace($s_Line, "(?:^.*), (\d{1,})(?:.*)", '$1'), $i_NewNumber)
MsgBox(0, '_Log_ErrorRoute', $s_Line)

;~ UpdateLineNumbers()
;~ MsgBox(0, 'Finished', 'All Done')

;~ Func UpdateLineNumbers($s_DirPath = @ScriptDir)
;~  Local $as_UDF = _FileListToArrayRec($s_DirPath, '*.au3|Update Line Number.au3|BackUp', $FLTAR_FILES, $FLTAR_RECUR, $FLTAR_NOSORT, $FLTAR_FULLPATH)
;~  If Not IsArray($as_UDF) Then Return MsgBox(0, @error, 'Error with FLTAR Extended: ' & @extended)

;~  Local $s_LineNumber = '' ; string returned by StringRegExpReplace
;~  Local $as_FileRead = 0 ; array for the file read

;~  ; loop through any udfs
;~  For $i = 1 To $as_UDF[0]
;~      If Not _FileReadToArray($as_UDF[$i], $as_FileRead) Then ; error reading the file to an array
;~          MsgBox(0, @error, 'Error reading ' & $as_UDF[$i])
;~          ContinueLoop
;~      Else
;~          ; loop through the open file array
;~          For $j = 1 To $as_FileRead[0]
;~              Select
;~                  Case StringInStr($as_FileRead[$j], '$i_LineNumber = ')
;~                      $s_LineNumber = StringRegExpReplace($as_FileRead[$j], "(?i)(?:^.*= )(\d{1,})(?:.*)", '$1') ; get the line number in the UDF

;~                  Case StringInStr($as_FileRead[$j], '__Msi_ErrorSetValues(')
;~                      $s_LineNumber = StringRegExpReplace($as_FileRead[$j], "(?:^.*\()(-?\d{1,})(?:.*)", '$1') ; get the line number in the UDF

;~                  Case StringInStr($as_FileRead[$j], '_Log_ErrorRoute(')
;~                      $s_LineNumber = StringRegExpReplace($as_FileRead[$j], "(?:^.*), (\d{1,})(?:.*)", '$1') ; get the line number in the UDF

;~                  Case Else
;~                      ContinueLoop
;~              EndSelect

;~              ; skip if ...
;~              If _
;~                      Not @extended _ ; no replacements made,
;~                      Or $s_LineNumber = '' _ ; returned string is blank
;~                      Or Number($s_LineNumber) < 1 _ ; returned string is less than 1
;~                      Or Number($s_LineNumber) = $j + 1 _ ; UDF line number matches the array line number
;~                      Then ContinueLoop

;~              ; update the line number with the array row + 1
;~              $as_FileRead[$j] = StringReplace($as_FileRead[$j], $s_LineNumber, $j + 1)
;~          Next

;~          _FileWriteFromArray($as_UDF[$i], $as_FileRead, 1)
;~          If @error Then MsgBox(0, @error, 'Unable to write to file ' & $as_UDF[$i])
;~      EndIf
;~  Next
;~ EndFunc   ;==>UpdateLineNumbers

 

Link to comment
Share on other sites

"as bulletproof as possible" obviously means : as precise/specific as possible

Local $s_Line1 = "Local $i_LineNumber = 133 ; some comment"
Local $i_NewNumber = 25
$s_Line1 = StringRegExpReplace($s_Line1, 'i_LineNumber = \K\d+', $i_NewNumber)
MsgBox(0, '$i_LineNumber', $s_Line1)

$s_Line2 = "__Msi_ErrorSetValues(133, '$o_Records.StringData[2]') ; update variables for future COM errors"
$s_Line2 = StringRegExpReplace($s_Line2, '__Msi_ErrorSetValues\(\K\d+', $i_NewNumber)
MsgBox(0, '__Msi_ErrorSetValues', $s_Line2)

$s_Line3 = "_Log_ErrorRoute('update', 'MSI', 133, '__Msi_ViewClose', '$o_View (' & IsObj($o_View) & ')')"
$s_Line3 = StringRegExpReplace($s_Line3, "_Log_ErrorRoute\('update', 'MSI', \K\d+", $i_NewNumber)
MsgBox(0, '_Log_ErrorRoute', $s_Line3)

Please note that as the patterns are similar, in your example it could eventually be done like this

Local $s_Lines = "Local $i_LineNumber = 133 ; some comment" & @crlf & _ 
    "__Msi_ErrorSetValues(133, '$o_Records.StringData[2]') ; update variables for future COM errors" & @crlf & _ 
    "_Log_ErrorRoute('update', 'MSI', 133, '__Msi_ViewClose', '$o_View (' & IsObj($o_View) & ')')"

$subpattern = "(i_LineNumber = |__Msi_ErrorSetValues\(|_Log_ErrorRoute\('update', 'MSI', )"

$s_Lines = StringRegExpReplace($s_Lines, $subpattern & "\K\d+", $i_NewNumber)
MsgBox(0, 'all', $s_Lines)

:)

Link to comment
Share on other sites

1 hour ago, mikell said:

"as bulletproof as possible" obviously means : as precise/specific as possible

Ideally, yes.  :). This should hopefully cut down the times I need to compare against the backup files if a compile error occurs after updating the line numbers. due to some unintentional code changes :(

Thanks for the trimmed down pattern, I had no idea about \K. There will be an issue with any line that has _Log_ErrorRoute because the passed parameter values are usually different. The 'update' and 'MSI' parts are string values that change depending on what the function is to do. I have attached a file that has the most occurrences of the strings as an example rather than a long explanation.

The replacements will also occur in a for\next loop (func UpdateLineNumbers commented out in post #1) so I won't be able to concatenate the lines

I will have a play with the pattern, Thanks

OI_MSI.au3

Edited by benners
Link to comment
Share on other sites

Wow, I see :blink:
Several occurences of _Log_ErrorRoute in the file but each with a different number ...
I didn't pay attention to the commented func in your post. effectively a better approach could probably be something like this - though it depends a lot on the way you plan to manage the changes

Local $s_Line1 = "Local $i_LineNumber = 133 ; some comment"

Local $i_OldNumber = StringRegExpReplace($s_Line1, '(?m)^.*i_LineNumber = (\d+).*', "$1")
Local $i_NewNumber = $i_OldNumber + 5

$s_Line1 = StringRegExpReplace($s_Line1, 'i_LineNumber = \K' & $i_OldNumber, $i_NewNumber)
MsgBox(0, '$i_LineNumber', $s_Line1)

 

Link to comment
Share on other sites

Thanks. Is the multi line required. The line string is read from an array so it will be on one line.

I have used the code below before, only replacing the first digit match, and have never come a cropper. Just for piece of mind though, I will get the line number first and check it against conditions as in the first post.

$i_NewNumber = 25
$s_Line3 = "_Log_ErrorRoute('update', 'MSI', 133, '__Msi_ViewClose', 12)"
$s_Line3 = StringRegExpReplace($s_Line3, "\d+", $i_NewNumber, 1)
MsgBox(0, '_Log_ErrorRoute', $s_Line3)

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...