Jump to content
benners

Using StringRegExpReplace to update line numbers

Recommended Posts

benners

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

 

Share this post


Link to post
Share on other sites
mikell

"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)

:)

  • Like 1

Share this post


Link to post
Share on other sites
benners
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

Share this post


Link to post
Share on other sites
mikell

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)

 

Share this post


Link to post
Share on other sites
benners

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)

 

Share this post


Link to post
Share on other sites
mikell

Multiline is useless if the string is a single line
In this case it's pretty simple and your code should work nice  :)

Share this post


Link to post
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

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.