; Script : Transform.kix
; Purpose: Check other scripts
; 'CHECK' (Syntakschecking: Strings, labels, variables loops and conditions are checked)
; 'CLEANUP' (Remove leading and trailing spaces and tabs)
; Options:
; 'TRANSFORM' (Same indent in entire script)
; 'COMPRESS' (Remove remarks and blank lines)
; Version 2.2 Juli 30, 2000 Erik KærholmBreak On
$Err = SetConsole("Maximize")
; Constants
$CRLF = Chr(13) + Chr(10)
$True = -1
$False = 0
$ValidChars = "_01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
; Chars valid in variable-names
$StrSep1 = "'"
$StrSep2 = '"'
$LogFile = %TEMP% + "\Transform.log"
; Statistic-vars
Dim $LabUsed[100]
$LabUsedNum = 0
Dim $LabDefined[100]
$LabDefinedNum = 0
Dim $SubCalled[100]
$SubCalledNum = 0
Dim $Vars[200]
Dim $VarsNumTab[200]
$VarsNum = 0
; Initialize
Color W+/b
$IndentNbr = 0
$LineNum = 0
$ErrorsFound = $False
$PosErrorsHead = $True
$Compress = $False
$LongLine = ""
$ErrorNum = 0
$TotErr = 0
$TotPosErr = 0
$Do = 0
;If $Do is greater than 0 when transform completes, $Do indicates missing Until(s)
;If Until-statements are met when $Do is 0, it indicates a missing Do-Statement
$If = 0
;If $If is greater than 0 when transform completes, $If indicates missing EndIf(s)
;If EndIf-statements are met when $If is 0, it indicates a missing If-Statement
$Select = 0
;If $Select is greater than 0 when transform completes, $Select indicates missing EndSelect(s)
;If EndSelect-statements are met when $Select is 0, it indicates a missing Select-Statement
$While = 0
;If $While is greater than 0 when transform completes, $While indicates missing Loop(s)
;If Loop-statements are met when $While is 0, it indicates a missing While-Statement
; *********************** Get user input **************************
Do
CLS
Box (1,1,3,78,"SINGLE")
AT (2,21) "T R A N S F O R M S C R I P T"
AT (5,5) "Script to transform : "
GetS $File
$Err = Open(1,"$File")
Until $Err = 0
If UCase(SubStr($File, Len($File) - 3, 4)) = ".ORG"
$OutFile = SubStr($File, 1, Len($File) - 4) + ".kix"
Else
$OutFile = $File + ".kix"
EndIf
$Err = SetFileAttr($OutFile, 128)
If $Err = 0
AT (7,5) "Overwrite " + $OutFile + " Y/N "
Do
Get $x
If UCase($x) = "N"
Return
EndIf
Until Ucase($x) = "Y"
"Y"
EndIf
$Indent = ""
AT (9,5) "Indent (T = Tabulator, 0..9 = number of spaces) : "
Do
Get $IndentIn
$IndentIn = UCase($IndentIn)
If $IndentIn = "T"
$Indent = Chr(9)
Else
$Test = Val($IndentIn)
If $Test > 0
$i = 0
While $i < $Test
$Indent = $Indent + " "
$i = $i + 1
Loop
EndIf
EndIf
Until $Indent <> "" Or $IndentIn = 0
$IndentIn
AT (11,5) "Keep remarks Y/N "
Do
Get $x
$x = UCase($x)
Until ($x = "Y") Or ($x = "N")
$x
If $x = "Y"
$KeepRemarks = $True
Else
$KeepRemarks = $False
EndIf
AT (13,5) "Keep empty lines Y/N "
Do
Get $x
$x = UCase($x)
Until ($x = "Y") Or ($x = "N")
$x
If $x = "Y"
$KeepEmptyLines = $True
Else
$KeepEmptyLines = $False
EndIf
If $IndentIn = 0 And $KeepRemarks = $False And $KeepEmptyLines = $False
$Compress = $True
$Seed = Val(SubStr("@Time",7,2))
$Seed=$Seed+1
Do
$x = Rnd(1)
$Seed = $Seed - 1
Until $Seed=0
EndIf
AT (17,5) "Checking line ......"
Del "$OutFile"
$Err = Open(2,"$OutFile",5)
; ******************** Initiate logfile *************************
$Err = SetFileAttr($LogFile, 128)
Del "$LogFile"
$Err = Open(3,"$LogFile",5)
$Err = WriteLine(3," T R A N S F O R M L O G" + $CRLF + $CRLF)
$Err = WriteLine(3,"Inputfile : " + $File + $CRLF)
$Err = WriteLine(3,"Outputfile: " + $OutFile + $CRLF + $CRLF)
$Err = WriteLine(3,"OPTIONS USED:" + $CRLF)
$Err = WriteLine(3," Indent : ")
$IndentIn = "" + $IndentIn
Select
Case $IndentIn = "T"
$Err = WriteLine(3,"Tabulator" + $CRLF)
Case $IndentIn = "0"
$Err = WriteLine(3,"NONE" + $CRLF)
Case 1
$Err = WriteLine(3,$IndentIn + " spaces" + $CRLF)
EndSelect
If $KeepRemarks
$Err = WriteLine(3," Remarks kept" + $CRLF)
Else
$Err = WriteLine(3," Remarks removed" + $CRLF)
EndIf
If $KeepEmptyLines
$Err = WriteLine(3," Empty lines kept" + $CRLF)
Else
$Err = WriteLine(3," Empty lines removed" + $CRLF)
EndIf
If $Compress
$Err = WriteLine(3," File: " + $OutFile + " is compressed, using long lines" + $CRLF)
EndIf
$Err = WriteLine(3, $CRLF)
; ************************ Main loop ****************************
$Line = ReadLine(1)
While @Error = 0
$LineNum = $LineNum + 1
AT(17, 26) $LineNum
GoSub WriteOutLine
$Line = ReadLine(1)
Loop
If $Compress
$Err = WriteLine(2, "$LongLine")
EndIf
; ****************** Complete and show log **********************
If $IndentNbr > 0
If $Do > 0
$TotErr = $TotErr + $Do
$ErrorNum = $Do
$ErrorType = "Until"
GoSub ErrorHandler
EndIf
If $If > 0
$TotErr = $TotErr + $If
$ErrorNum = $If
$ErrorType = "EndIf"
GoSub ErrorHandler
EndIf
If $Select > 0
$TotErr = $TotErr + $Select
$ErrorNum = $Select
$ErrorType = "EndSelect"
GoSub ErrorHandler
EndIf
If $While > 0
$TotErr = $TotErr + $While
$ErrorNum = $While
$ErrorType = "Loop"
GoSub ErrorHandler
EndIf
EndIf
AT (19,5) "Checking labels and variables ......"
GoSub CheckGoSub
GoSub CheckGoTo
GoSub CheckLabels
GoSub CheckVars
$Err = WriteLine(3,$CRLF)
If $ErrorsFound
$OutLine = $OutFile + " created with "
If $TotErr > 0
$OutLine = $OutLine + $TotErr + " Error(s)"
If $TotPosErr > 0
$OutLine = $OutLine + " and " + $TotPosErr + " possible error(s)"
EndIf
Else
$OutLine = $OutLine + $TotPosErr + " possible error(s)"
EndIf
$Err = WriteLine(3,$OutLine + $CRLF)
$Err = WriteLine(3,"Correct errors in " + UCase($File) + " and transform again" + $CRLF + $CRLF)
Else
$Err = WriteLine(3,$OutFile + " successfully created, no errors found." + $CRLF + $CRLF)
EndIf
$Err = WriteLine(3,"Statistics:" + $CRLF)
$Err = WriteLine(3," Number of Variables = " + $VarsNum + $CRLF)
$Err = WriteLine(3," Number of GoSub Statements = " + $SubCalledNum + $CRLF)
$Err = WriteLine(3," Number of GoTo Statements = " + $LabUsedNum + $CRLF)
$Err = WriteLine(3," Number of Labels = " + $LabDefinedNum)
$Err = Close(1)
$Err = Close(2)
$Err = Close(3)
Run "NotePad.exe $LogFile"
If @Error
AT(21,5) "Check logfile: " + $LogFile + " for errors"
AT(23,5) "Press any key to exit"
Get $x
EndIf
Return ; END SCRIPT
;***************
:WriteOutLine
;***************
; Remove leading spaces and tabs
While (SubStr($Line,1,1) = " ") Or (SubStr($Line,1,1) = Chr(9))
$Line = SubStr($Line, 2, Len($Line) - 1)
Loop
; Remove trailing spaces and tabs
While (SubStr($Line,Len($Line),1) = " ") Or (SubStr($Line,Len($Line),1) = Chr(9))
$Line = SubStr($Line, 1, Len($Line) - 1)
Loop
; Split code and remarks
$TmpLine = $Line
$PosRem = 0
GoSub GetPosRem
If $PosRem = 0
$TmpLine = $Line
GoSub TestStrings
EndIf
$FrontRem = ""
If $PosRem > 0
If $PosRem > 1
$FrontRem = $Indent
EndIf
$Remark = SubStr($Line, $PosRem , Len($Line) - $PosRem + 1)
$Code = SubStr($Line, 1, $PosRem - 1)
Else
$Remark = ""
$Code = $Line
EndIf
; Remove trailing spaces and tabs from code
While (SubStr($Code,Len($Code),1) = " ") Or (SubStr($Code,Len($Code),1) = Chr(9))
$Code = SubStr($Code, 1, Len($Code) - 1)
Loop
; Check if line is empty
If $Code = "" And $Remark = ""
$LineEmpty = $True
Else
$LineEmpty = $False
EndIf
$PendingIndent = 0
If $Code <> "" ; Code = Line stripped for remarks and leading/trailing spaces and tabs
; Check for reserved, words expected to be entire code
$NotChecked = $False
$Test = UCase($Code)
Select
Case $Test = "DO"
$PendingIndent = 1
$Do = $Do + 1
Case $Test = "ELSE"
$PendingIndent = 1
$IndentNbr = $IndentNbr - 1
Case $Test = "ENDIF"
If $If > 0
$IndentNbr = $IndentNbr - 1
$If = $If - 1
Else
$ErrorType = "If"
GoSub ErrorHandler
EndIf
Case $Test = "SELECT"
$Select = $Select + 1
$PendingIndent = 1
$CasePrev = $False
Case $Test = "ENDSELECT"
If $Select > 0
$IndentNbr = $IndentNbr - 2
$Select = $Select - 1
Else
$ErrorType = "Select"
GoSub ErrorHandler
EndIf
Case $Test = "LOOP"
If $While > 0
$IndentNbr = $IndentNbr - 1
$While = $While - 1
Else
$ErrorType = "While"
GoSub ErrorHandler
EndIf
Case 1
$NotChecked = $True
EndSelect
If $NotChecked
; Check for reserved words expected to be part of code
If SubStr($Test, 1, 3) = "IF "
If SubStr($Test, Len($Test) - 5, 6) <> " ENDIF"
$PendingIndent = 1
$If = $If + 1
EndIf
Else
If SubStr($Test, 1, 5) = "CASE "
$PendingIndent = 1
If $CasePrev
$IndentNbr = $IndentNbr - 1
Else
$CasePrev = $True
EndIf
Else
If SubStr($Test, 1, 6) = "UNTIL "
If $Do > 0
$IndentNbr = $IndentNbr - 1
$Do = $Do - 1
Else
$ErrorType = "Do"
GoSub ErrorHandler
EndIf
Else
If SubStr($Test, 1, 6) = "WHILE "
$PendingIndent = 1
$While = $While + 1
Else
If SubStr($Test, 1, 6) = "GOSUB "
$LabName = Ltrim(RTrim(SubStr($Test, 7, Len($Test) - 6)))
GoSub SubInfo
Else
If SubStr($Test, 1, 5) = "GOTO "
$LabName = Ltrim(RTrim(SubStr($Test, 6, Len($Test) - 5)))
GoSub LabInfo
Else
If SubStr($Test, 1, 1) = ":"
$LabName = SubStr($Test, 2, Len($Test) - 1)
GoSub LabDefined
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
EndIf
GoSub CountVars
EndIf
; *********************** Create line ***************************
; ********* Compile Line from indents, code and remarks *********
If $Code <> ""
$i = 0
$Front = ""
While $i < $IndentNbr
$Front = $Front + $Indent
$i = $i + 1
Loop
$Line = $Front + $Code
Else
$Line = ""
EndIf
If ($Remark <> "") And $KeepRemarks
If $Line <> ""
$Line = $Line + $FrontRem
EndIf
$Line = $Line + $Remark
EndIf
If $Line <> ""
If $Compress
If $LongLine = ""
$LongLine = $Line
Else
$Rnd = Rnd(34)
Select
Case $Rnd < 20
$Del = Chr(9)
Case $Rnd < 33
$Del = " "
Case 1
$Del = Chr(10)
EndSelect
$LongLine = $LongLine + $Del + $Line
EndIf
If Len($LongLine) > 500
$LineShift = $True
$Line = $LongLine
$LongLine = ""
Else
$LineShift = $False
EndIf
Else
$LineShift = $True
EndIf
EndIf
If $LineShift
If $Line <> ""
$Line = $Line + $CRLF
Else
If $KeepEmptyLines And $LineEmpty
$Line = $CRLF
EndIf
EndIf
$Err = WriteLine(2, "$Line")
EndIf
$IndentNbr = $IndentNbr + $PendingIndent
Return ; *END SUB* WriteOutLine
;**************
:GetPosRem
;**************
$TestRem = InStr($TmpLine, ";")
If $TestRem > 0
$TstStr1 = InStr($TmpLine, $StrSep1)
If $TstStr1 = 0
$TstStr1 = 100000
EndIf
$TstStr2 = InStr($TmpLine, $StrSep2)
If $TstStr2 = 0
$TstStr2 = 100000
EndIf
If $TstStr1 < $TstStr2
$StrSep = $StrSep1
$StartStr = $TstStr1
Else
$StrSep = $StrSep2
$StartStr = $TstStr2
EndIf
If $StartStr = 100000
$StartStr = 0
EndIf
If $StartStr < $TestRem And $StartStr > 0
$PosRem = $PosRem + $StartStr
$TmpLine = SubStr($TmpLine, $StartStr + 1, Len($TmpLine) - $StartStr)
$TestRem = InStr($TmpLine, ";")
$TestEnd = InStr($TmpLine, $StrSep)
If $TestEnd > 0
If $TestEnd > $TestRem
$PosRem = $PosRem + $TestEnd
$TmpLine = SubStr($TmpLine, $TestEnd + 1, Len($TmpLine) - $TestEnd)
GoSub GetPosRem
Else
$PosRem = $PosRem + $TestRem
EndIf
Else
If $ErrorsFound = $False
$Err = WriteLine(3,"Error(s):" + $CRLF)
EndIf
$TotErr = $TotErr + 1
$ErrorsFound = $True
$Err = WriteLine(3," Mismatching stringdelimitors in line " + $LineNum + $CRLF)
$PosRem = 0
$TmpLine = ""
EndIf
Else
$PosRem = $PosRem + InStr($TmpLine, ";")
Endif
Else
$PosRem = 0
EndIf
Return ;*END SUB* GetPosRem
;**************
:TestStrings
;**************
$TstStr1 = InStr($TmpLine, $StrSep1)
If $TstStr1 = 0
$TstStr1 = 100000
EndIf
$TstStr2 = InStr($TmpLine, $StrSep2)
If $TstStr2 = 0
$TstStr2 = 100000
EndIf
If $TstStr1 < $TstStr2
$StrSep = $StrSep1
$StartStr = $TstStr1
Else
$StrSep = $StrSep2
$StartStr = $TstStr2
EndIf
If $StartStr = 100000
$StartStr = 0
EndIf
If $StartStr > 0
$TmpLine = SubStr($TmpLine, $StartStr + 1, Len($TmpLine) - $StartStr)
$TestEnd = InStr($TmpLine, $StrSep)
If $TestEnd > 0
$TmpLine = SubStr($TmpLine, $TestEnd + 1, Len($TmpLine) - $TestEnd)
GoSub TestStrings
Else
If $ErrorsFound = $False
$Err = WriteLine(3,"Error(s):" + $CRLF)
EndIf
$TotErr = $TotErr + 1
$ErrorsFound = $True
$Err = WriteLine(3," Mismatching stringdelimitors in line " + $LineNum + $CRLF)
$TmpLine = ""
EndIf
EndIf
Return ; *END SUB* TestStrings
;**************
:ErrorHandler
;**************
If $ErrorsFound = $False
$Err = WriteLine(3,"Error(s):" + $CRLF)
EndIf
If $ErrorNum > 0
$Err = WriteLine(3," Missing " + $ErrorNum + " " + $ErrorType + " statement(s)" + $CRLF)
Else
$TotErr = $TotErr + 1
$Err = WriteLine(3," Missing " + $ErrorType + " statement before line " + $LineNum + $CRLF)
EndIf
$ErrorsFound = $True
Return ; *END SUB* ErrorHandler
;**************
:SubInfo
;**************
If SubStr($LabName, 1, 1) = $StrSep1 Or SubStr($LabName, 1, 1) = $StrSep2
$LabName = SubStr($LabName, 2, Len($LabName) - 2)
EndIf
$SubCalledNum = $SubCalledNum + 1
$SubCalled[$SubCalledNum] = $LabName + "," + $LineNum
Return ; *END SUB* SubInfo
;**************
:LabInfo
;**************
If SubStr($LabName, 1, 1) = $StrSep1 Or SubStr($LabName, 1, 1) = $StrSep2
$LabName = SubStr($LabName, 2, Len($LabName) - 2)
EndIf
$LabUsedNum = $LabUsedNum + 1
$LabUsed[$LabUsedNum] = $LabName + "," + $LineNum
Return ; *END SUB* LabInfo
;**************
:LabDefined
;**************
Dim $i, $NotFound
$i = 1
$NotFound = $True
While $i <= $LabDefinedNum And $NotFound
If $LabName = $LabDefined[$i]
$NotFound = $False
Else
$i = $i + 1
EndIf
Loop
If $NotFound
$LabDefinedNum = $LabDefinedNum + 1
$LabDefined[$LabDefinedNum] = $LabName
Else
If $ErrorsFound = $False
$Err = WriteLine(3,"Error(s):" + $CRLF)
EndIf
$TotErr = $TotErr + 1
$Err = WriteLine(3," Label " + $LabName + " defined more than once" + $CRLF)
$ErrorsFound = $True
EndIf
Return ; *END SUB* LabDefined
;**************
:CountVars
;**************
Dim $i, $Var, $ChkLine, $Pos, $Len, $ChkChar, $NotFound, $DoubleDollar
$ChkLine = $Code
While Instr($ChkLine, "$")
$Pos = Instr($ChkLine, "$")
$ChkLine = SubStr($ChkLine, $Pos + 1, Len($ChkLine) - $Pos)
$Len = Len($ChkLine)
If $Len > 0
$ChkChar = SubStr($ChkLine, 1, 1)
If $ChkChar = "$"
; Use of $$ to output variable-name, NOT a variable
If $Len > 1
$ChkLine = SubStr($ChkLine, 2, $Len - 1)
Else
$ChkLine = ""
EndIf
$DoubleDollar = $True
Else
$DoubleDollar = $False
EndIf
EndIf
If $DoubleDollar = $False
$Var = "$"
While InStr($ValidChars, $ChkChar) And ($Len > 0)
$Var = $Var + $ChkChar
If $Len > 1
$ChkLine = SubStr($ChkLine, 2, $Len - 1)
EndIf
$ChkChar = SubStr($ChkLine, 1, 1)
$Len = $Len - 1
Loop
$i = 1
$NotFound = $True
While $i <= $VarsNum And $NotFound
If $Vars[$i] = $Var
$NotFound = $False
$VarsNumTab[$i] = $VarsNumTab[$i] + 1
Else
$i = $i + 1
EndIf
Loop
If $NotFound And $Var <> "$"
; $Var = "$" idicates word ending with $ i.e. a hidden share
$VarsNum = $VarsNum + 1
$Vars[$VarsNum] = $Var
$VarsNumTab[$VarsNum] = 1
EndIf
EndIf
Loop
Return ; *END SUB* CountVars
;**************
:CheckGoTo
;**************
Dim $i, $j, $Pos, $Len, $NotFound, $TestName, $LineNum, $LabU
$i = 1
While $i <= $LabUsedNum
$LabU = $LabUsed[$i]
$Pos = InStr($LabU, ",")
$TestName = SubStr($LabU, 1, $Pos - 1)
$NotFound = $True
$j = 1
While $j <= $LabDefinedNum And $NotFound
If $TestName = $LabDefined[$j]
$NotFound = $False
EndIf
$j = $j + 1
Loop
If $NotFound
If $ErrorsFound = $False
$Err = WriteLine(3,"Error(s):" + $CRLF)
EndIf
$TotErr = $TotErr + 1
$Len = Len($LabU)
$LineNum = SubStr($LabU, $Pos + 1, $Len - $Pos)
$Err = WriteLine(3," Label missing for GoTo " + $TestName + " in line " + $LineNum + $CRLF)
$ErrorsFound = $True
EndIf
$i = $i + 1
Loop
Return ; *END SUB* CheckGoTo
;**************
:CheckGoSub
;**************
Dim $i, $j, $Pos, $Len, $NotFound, $TestName, $LineNum, $SubC
$i = 1
While $i <= $SubCalledNum
$SubC = $SubCalled[$i]
$Pos = InStr($SubC, ",")
$TestName = SubStr($SubC, 1, $Pos - 1)
$NotFound = $True
$j = 1
While $j <= $LabDefinedNum And $NotFound
If $TestName = $LabDefined[$j]
$NotFound = $False
EndIf
$j = $j + 1
Loop
If $NotFound
If $ErrorsFound = $False
$Err = WriteLine(3,"Error(s):" + $CRLF)
EndIf
$TotErr = $TotErr + 1
$Len = Len($SubCalled[$i])
$LineNum = SubStr($SubCalled[$i], $Pos + 1, $Len - $Pos)
$Err = WriteLine(3," Subroutine (label) missing for GoSub " + $TestName + " in line " + $LineNum + $CRLF)
$ErrorsFound = $True
EndIf
$i = $i + 1
Loop
Return ; *END SUB* CheckGoSub
;**************
:CheckVars
;**************
Dim $i
$i = 1
While $i <= $VarsNum
If $VarsNumTab[$i] = 1
If $PosErrorsHead
$Err = WriteLine(3,$CRLF + "Possible Error(s):" + $CRLF)
$PosErrorsHead = $False
EndIf
$TotPosErr = $TotPosErr + 1
$Err = WriteLine(3," Variable: " + $Vars[$i] + " only used once! (maybe defined but not used)" + $CRLF)
$ErrorsFound = $True
EndIf
$i = $i + 1
Loop
Return ; *END SUB* CheckVars
;**************
:CheckLabels
;**************
Dim $i, $j, $Pos, $NotFound, $TestName, $Label
$i = 1
While $i <= $LabDefinedNum
$Label = $LabDefined[$i]
$NotFound = $True
$j = 1
While $j <= $SubCalledNum And $NotFound
$TestName = $SubCalled[$j]
$Pos = InStr($TestName, ",")
$TestName = SubStr($TestName, 1, $Pos - 1)
If $TestName = $Label
$NotFound = $False
EndIf
$j = $j + 1
Loop
If $NotFound
$j = 1
While $j <= $LabUsedNum And $NotFound
$TestName = $LabUsed[$j]
$Pos = InStr($TestName, ",")
$TestName = SubStr($TestName, 1, $Pos - 1)
If $TestName = $Label
$NotFound = $False
EndIf
$j = $j + 1
Loop
EndIf
If $NotFound
If $PosErrorsHead
$Err = WriteLine(3,$CRLF + "Possible Error(s):" + $CRLF)
$PosErrorsHead = $False
EndIf
$TotPosErr = $TotPosErr + 1
$Err = WriteLine(3," Label: " + $Label + " defined but not used" + $CRLF)
$ErrorsFound = $True
EndIf
$i = $i + 1
Loop
Return ; *END SUB* CheckLabels