;========================================================================================================================================== ; ; How to strip/merge comments from/to WBT source file? ; ;========================================================================================================================================== ;========================================================================================================================================== ; Name: ; StripAndMergeComments.wbt ; ; Purpose: ; Remove comments from WinBatch source code file. ; Create related comment list file. ; Create new anonymous comment-less wbt code file for production environment. ; Merge previously stripped comments with production code file giving back complete source code file. ; ; Note: ; This feasibility study contains only rudimentary error or consistency checking. ; ;------------------------------------------------------------------------------------------------------------------------------------------ ; ; Author: ; Detlev Dalitz.20090411.20120110. ; ; With contributions from: ; Les Ferch.20090410. ; ; Based on the motivating request from: ; Doug Blaze.20090410. ; ;------------------------------------------------------------------------------------------------------------------------------------------ ; ; This theme is based on: ; ; Topic: Remove comments from code ; Conf: WinBatch ; From: dblaze1 ; Date: Friday, April 10, 2009 01:14 PM ; ; We're going to be undergoing a security audit that includes reviewing our coding policies and ; ... we were told by a QSA consultant that it is bad practice to have commented code in a production environment. ; ... He said it just gives information to someone who breaks in and gets hold of the code - which makes sense. ; ... He said the correct way of doing it is to make a production copy in which all comments are removed. ; ... Now, I don't know about the rest of you, but I add lots of comments to my code and it would take forever ; to have to remove them all before moving to a production environment. ; ... Has anyone heard of this before? ; ... Has anyone attempted to do this with Winbatch? ; Thanks, ; Doug ;========================================================================================================================================== ; Test comment 1. ; Test comment 2. : This comment is intentionally indented. ; Test comment 3. GoSub Define_Functions blnResult = DirChange (DirScript ()) strThisScript = IntControl (1004, 0, 0, 0, 0) ; The original source file. ; strFileWbt = "W:\Folder\WinbatchScriptFile.wbt" strFileWbt = strThisScript ; We use this script file as test input. ; Files to be created. strFileProd = ItemReplace (`prod.wbt`, -1, strThisScript, `.`) ; The "Production File': to be used in the wild. strFileComment = ItemReplace (`comment.txt`, -1, strThisScript, `.`) ; The 'Comment File' ..: to be used for maintenance purposes. strFileMerged = ItemReplace (`merged.wbt`, -1, strThisScript, `.`) ; The 'Merged File' ...: to be used for maintenance purposes. :Step1 ; Remove comments from wbt script and save them to external CSV file. udfRemoveWbtComments (strFileWbt, strFileProd, strFileComment) :Step2 ; Restore comments from external CSV file. If udfCheckFileCsv (strFileComment, ",", @TRUE) udfRestoreWBTComments (strFileMerged, strFileComment) EndIf :Step3 ; Display all involved files. strWBStudio = DirHome () : `WinBatch Studio.exe` Run (strWBStudio, `"` : strFileProd : `"`) Run (strWBStudio, `"` : strFileComment : `"`) Run (strWBStudio, `"` : strFileMerged : `"`) :CANCEL Exit ;========================================================================================================================================== :Define_Functions ;========================================================================================================================================== ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfSplitWbtCodeLine (strLine) y = 0 z = 0 strQuoteChars = `'` : `"` : "`" While @TRUE x = StrScan (strLine, strQuoteChars, y + 1, @FWDSCAN) If x == 0 Then Break strQuoteChar = StrSub (strLine, x, 1) z = y y = StrIndex (strLine, strQuoteChar, x + 1, @FWDSCAN) If y == 0 y = z Break EndIf EndWhile x = StrIndex (strLine, `;`, y + 1, @FWDSCAN) strComment = `` If x > 0 strComment = StrSub (strLine, x, -1) strLine = StrSub (strLine, 1, x - 1) EndIf Return Arrayize (strLine : @LF : strComment, @LF) ;.......................................................................................................................................... ; This UDF "udfSplitWbtCodeLine" was originally designed to remove a comment which follows the code on the same line. ; Now the returning dim-1 array contains both parts of the line: the code part and the comment part. ; ; Les Ferch.20090410. ; Detlev Dalitz.????????.20090411. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfRemoveWbtComments (strFileWbt, strFileProd, strFileComment) arrData = ArrayFileGet (strFileWbt) intDataLines = ArrInfo (arrData, 1) intDataLast = intDataLines - 1 arrNew = ArrDimension (intDataLines) arrComment = ArrDimension (intDataLines + 1, 3) ; Dim-2 array, will be saved as CSV array. intNumberFmt = StrLen (intDataLines) ; Measure width of the last line number. intCommentNr = 0 For intElem = 0 To intDataLast strLine = arrData [intElem] intLineNr = intElem + 1 If 1 == StrIndex (StrTrim (strLine), `;`, 1, @FWDSCAN) intCommentNr = intCommentNr + 1 strCommentFmt = StrFixLeft (intCommentNr, `0`, intNumberFmt) strLineNrFmt = StrFixLeft (intLineNr, `0`, intNumberFmt) arrComment [intElem, 0] = strLineNrFmt arrComment [intElem, 1] = strCommentFmt arrComment [intElem, 2] = StrTrim (strLine) arrNew [intElem] = StrFill (` `, StrIndex (strLine, `;`, 1, @FWDSCAN) - 1) : `; #` : strCommentFmt Else arrTmp = udfSplitWbtCodeLine (strLine) arrNew [intElem] = arrTmp [0] If arrTmp [1] != `` intCommentNr = intCommentNr + 1 strCommentFmt = StrFixLeft (intCommentNr, `0`, intNumberFmt) strLineNrFmt = StrFixLeft (intLineNr, `0`, intNumberFmt) arrComment [intElem, 0] = strLineNrFmt arrComment [intElem, 1] = strCommentFmt arrComment [intElem, 2] = arrTmp [1] arrNew [intElem] = arrTmp [0] : `; #` : strCommentFmt EndIf EndIf Next arrComment [intDataLast + 1, 0] = intDataLines arrComment [intDataLast + 1, 1] = strCommentFmt arrComment [intDataLast + 1, 2] = strFileProd intBytesWritten = ArrayFilePutCSV (strFileComment, arrComment) intBytesWritten = ArrayFilePut (strFileProd, arrNew) ; For sure delete empty lines from comment file. strData = FileGet (strFileComment) strSearch = @CRLF : @CRLF While !!StrIndex (strData, strSearch, 1, @FWDSCAN) strData = StrReplace (strData, strSearch, @CRLF) EndWhile intBytesWritten = FilePut (strFileComment, strData) ; Test comment 4. : This comment is inline. Return ;.......................................................................................................................................... ; This UDF "udfRemoveWbtComments" removes comments from WBT source text ... ; ... and creates two text files: ; - the 'Production File', with all the literal comment strings replaced by placeholder token; ; - the 'Comment File', with all the comments from the original wbt script file. ; ; Les Ferch.20090410. ; Detlev Dalitz.20090411..20120110. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfRestoreWBTComments (strFileMerged, strFileComment) arrComment = ArrayFileGetCSV (strFileComment, 0, `,`) intCommentLines = ArrInfo (arrComment, 1) intCommentLast = intCommentLines - 1 strFileWbt = arrComment [intCommentLast, 2] intCommentLast = intCommentLast - 1 arrData = ArrayFileGet (strFileWbt) intDataLines = ArrInfo (arrData, 1) intDataLast = intDataLines - 1 For intElem = 0 To intCommentLast intLineNr = arrComment [intElem, 0] intCommentNr = arrComment [intElem, 1] intCommentText = arrComment [intElem, 2] strTemp = arrData [intLineNr - 1] strTemp = StrReplace (strTemp, `; #` : intCommentNr, intCommentText) arrData [intLineNr - 1] = strTemp Next intBytesWritten = ArrayFilePut (strFileMerged, arrData) Return ;.......................................................................................................................................... ; This UDF "udfRestoreWBTComments" restores all the comments from the comment ressource CSV file ... ; ... and creates the 'Merged' file with all the code lines and comments merged together, giving back the original WBT source file. ; ; Detlev Dalitz.20090411.20120110. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;----------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfCheckFileCsv (strFileCsv, strDelimiter, blnTrim) IntControl (72, 1, @TRUE, "", 0) ; On next cancel event goto label :CANCEL. IntControl (73, 0, @TRUE, "", 0) ; p2=0 Normal error processing (default). blnResult = @TRUE If !!blnTrim Then udfTrimFile (strFileCsv) ; Remove leading and trailing empty lines. intLastEM = ErrorMode (@OFF) LastError () arrCsv = ArrayFileGetCSV (strFileCsv, 0, strDelimiter) intLastError = LastError () ErrorMode (intLastEM) If intLastError > 0 ; Possible error message can be: 1808 File contains invalid CSV line(s). blnResult = @FALSE Pause ("udfCheckFileCsv | Error in CSV File", "File: " : strFileCsv : @LF : @LF : wberroradditionalinfo : @LF : @LF : "Repair CSV data and try again.") EndIf :CANCEL Return blnResult ;.......................................................................................................................................... ; This UDF "udfCheckFileCsv" is a simple helper to check a given CSV file for possible formatting errors. ; ; The checkup itself relies on the built-in rules of the WinBatch function ArrayFileGetCSV. ; If an input line cannot be accepted to be a correct CSV line, then the function ArrayFileGetCSV ; returns the minor error "1808 File contains invalid CSV line(s)" and provides a hint on which line the error has been occurred. ; This UDF catches the error and offers a simple message to the user. ; ; This UDF expects that the given CSV File ; - has @CRLF end of line delimiters; ; - has not any @TAB character; ; - allows read and write access when removing leading and trailing empty lines. ; ; This UDF returns the boolean value @TRUE (1) or @FALSE (0) to indicate that the given file can be used as a CSV file or not. ; ; Detlev Dalitz.20100814.20120110 ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;------------------------------------------------------------------------------------------------------------------------------------------ #DefineFunction udfTrimFile (strFilename) strText = FileGet (strFilename) If strText == "" Then Return 0 ; No Change. If strText == @CRLF Then Return FilePut (strFilename, "") ; Write empty file. strText = StrTrim (FileGet (strFilename)) If strText == "" Then Return FilePut (strFilename, "") ; Write empty file. intPosL = 1 While intPosL == StrIndex (strText, @CRLF, intPosL, @FWDSCAN) intPosL = intPosL + 2 EndWhile intPosR = StrByteCount (strText, -1) - 1 While intPosR == StrIndex (strText, @CRLF, intPosR, @FWDSCAN) intPosR = intPosR - 2 EndWhile strText = StrSub (strText, intPosL, 2 + IntPosR - intPosL) : @CRLF If strText == FileGet (strFilename) Then Return 0 ; No change. Return FilePut (strFilename, strText) ; Write trimmed file. ;------------------------------------------------------------------------------------------------------------------------------------------ ; This UDF "udfTrimFile" removes leading and trailing blank lines from the given text file. ; The return value is the number of bytes written to the disk file. ; ; Detlev Dalitz.20120110. ;.......................................................................................................................................... #EndFunction ;------------------------------------------------------------------------------------------------------------------------------------------ ;========================================================================================================================================== Return ; from GoSub Define_Functions ;========================================================================================================================================== ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Reduced example of an anonymous comment-less wbt production file. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; #001 ; ; #002 ; ; #003 ; ; #004 ; ; #005 ; ; #006 ; ; #007 ; ; #008 ; ; #009 ; ; ; #010 ; #DefineFunction StripComment (strLine) ; ... ; #EndFunction ; ; ; #011 ; #DefineFunction RemoveWBTComments (strFileWbt, strNewFile, strFileComment) ; ... ; intLineNr = intElem + 1 ; ; #012 ; If StrSub (StrTrim (strLine), 1, 1) == `;` ; ... ; intBytesWritten = ArrayFilePut (strNewFile, arrNew) ; ; ; #013 ; strData = FileGet (strFileComment) ; ... ; #EndFunction ; ; ; #014 ; blnResult = DirChange (DirScript ()) ; strThisScript = IntControl (1004, 0, 0, 0, 0) ; #015 ; ... ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; CSV-Format of the related comment file. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; Comment entries: ; Col-1 = Line number within code file. ; Col-2 = Comment number. ; Col-3 = Comment text. ; ; Footer line: ; Col-1 = Number of lines in production file. ; Col-2 = Number of comment replacements. ; Col-3 = Filepath to the corresponding production file. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; "001","001",";~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ; "002","002","; Name: StripComments.wbt" ; "003","003","; Create new anonymous comment-less wbt code file." ; "005","005","; Create related comment list file." ; "006","006",";~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ; "007","007","; Author: Les Ferch." ; "008","008","; Modified by: Detlev Dalitz.20090411." ; "009","009",";~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ; "011","010","; This function is called by the main function to remove comments on same Line as code." ; "036","011","; Call this function to remove comments from WBT source." ; "048","012","; Test: This comment is indented." ; "070","013","; Delete empty lines from comment file." ; "079","014","; Test." ; "081","015","; Test: This comment is inline." ; "119","015","W:\WINBATCH\TEST\2009\20090410.Test.Remove comments from code.prod.wbt" ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~