benners Posted December 10, 2017 Share Posted December 10, 2017 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. expandcollapse popup#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 More sharing options...
mikell Posted December 10, 2017 Share Posted December 10, 2017 "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) benners 1 Link to comment Share on other sites More sharing options...
benners Posted December 10, 2017 Author Share Posted December 10, 2017 (edited) 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 December 10, 2017 by benners Link to comment Share on other sites More sharing options...
mikell Posted December 10, 2017 Share Posted December 10, 2017 Wow, I see 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 More sharing options...
benners Posted December 11, 2017 Author Share Posted December 11, 2017 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 More sharing options...
mikell Posted December 11, 2017 Share Posted December 11, 2017 Multiline is useless if the string is a single line In this case it's pretty simple and your code should work nice Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now