Freelancer "linting" script - commandline junkies
Below is VBScript code that can be used to 'lint' a Freelancer data INI file (e.g., decoded BINI files - won't work for Freelancer.ini, etc.). It is no-frills at this point, and has to be executed from the commandline. Here's how to use it; instructions are intended for people already comfortable with the commandline.
1 - Make sure you have WSH 5.6 installed; it comes with Windows XP and newer already, or can be downloaded from Microsoft's Scripting Technologies web site.
2 - Save the code to a file with a .vbs extension; for example, flint.vbs.
3. - Run it. You need to explicitly use the WSH console variant (cscript) to execute the script, and redirect input from the file you want to test. So for example, if you saved the file to "C:\My Temp Files\flint.vbs" and want to test
"C:\Program Files\Microsoft Games\Freelancer\DATA\SHIPS\shiparch.ini", you would do this:
<pre><font size=1 face=Courier>cscript "C:\My Temp Files\flint.vbs" < "C:\Program Files\Microsoft Games\Freelancer\DATA\SHIPS\shiparch.ini" </font></pre>
Note that this isn't very useful for testing stock files or FL SDK files; the "errors" it will pick up are either errors Freelancer is theoretically able to handle OK or apparently correct usage (such as the "assertion" lines in navbar.ini - behavior/mesh/event etc.)
<pre><font size=1 face=Courier>
' Parses a decompressed Freelancer INI file looking for possible errors.
' Copyright: This is my work and I hereby place it in the public domain.
Option Explicit
Dim namedArgs: Set namedArgs = WScript.Arguments.Named
' m_Warn controls whether warnings for bad values are shown.
Dim m_Warn: m_Warn = True
If namedArgs.Exists("W" ) and namedArgs("W" ) = False Then
m_Warn = False
End If
' Set this flag if we want good data written to stdout.
Dim m_Output: m_Output = False
If namedArgs.Exists("O" ) Then m_Output = True
' Global declaration of the regex used in procedure TrimNoise().
Dim rx: set rx = New Regexp: rx.Global = True
' This is a quick regex for whitespacish characters. In theory, most should
' never show up in a data segment, but let's be cautious anyway.
' This will also make sure we treat ASCII 160 as a space.
' The NON-noise set is thus the following:
' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO
' PQRSTUVWXYZ[\^_`abcdefghijklmnopqrstuvwxyz{/}~
Const noisePattern = "[\x00-\x20\x7f-\xff+"
'Main processing loop
Do While Not WScript.StdIn.AtEndofStream
Dim originalData: originalData = WScript.StdIn.ReadLine()
Dim data: data = TrimNoise(TrimComments(originalData))
If Len(data) = 0 Then
' This is just a spacing line; pass it on.
WriteOutput vbNullString
ElseIf Left(data, 1) = "[" Then
' Looks like a header
If Right(data, 1) <> Chr(93) Then
' Looks like a malformed header
' Chr(93) is a close bracket; using this to handle LTR forum posting.
WriteWarning WScript.StdIn.Line - 1, originalData, _
"This may be a bad header."
Else
' Looks good; write it.
WriteOutput data
End If
ElseIf Right(data, 1) = Chr(93) Then
' Looks like a malformed header
' Chr(93) is a close bracket; using this to handle LTR forum posting.
WriteWarning WScript.StdIn.Line - 1, originalData, _
"This may be a bad header."
Else
' This looks like a data line. Check for '='.
Dim elements: elements = Split(data, "=" )
Select Case UBound(elements)
Case 0, -1
' Only 1 element. This is apparently anomalous other than in
' \Data\Interface\Baseside\navbar.ini
WriteWarning WScript.StdIn.Line - 1, originalData, _
"No '=' found; may be anomalous value unless in navbar.ini."
' We still write it out since it is possibly OK and since
' Freelancer seems to cope with it OK.
WriteOutput data
Case 1
elements(0) = TrimNoise(0): elements(1) = TrimNoise(1)
if Len(elements(0)) = 0 or Len(elements(1)) = 0 Then
' We are missing a name or a value. This is an error.
WriteWarning WScript.StdIn.Line - 1, originalData, _
"Missing a keyname or a value."
Else
' Looks good; write it out.
WriteOutput Join(elements, " = " )
End If
Case Else
WriteWarning WScript.StdIn.Line - 1, originalData, _
"Extra '=' in data."
End Select
End If
Loop
' End of main processing loop; the rest of this is declarations
' of procedures used in code above.
function TrimComments(ByVal s)
' this is specifically designed to strip extraneous material
' from a decompressed Freelancer Ini file line.
TrimComments = vbNullString
' we leave if a line is empty
If len(s) = 0 Then Exit Function
' we assume there is NO way a semicolon can be meaningful data.
' There is one possible exception; a quoted semicolon in keymap.ini
' could cause a problem; we eventually need to fix this.
' For now, it is probably better to work it this way.
Dim semicolon: semicolon = ";"
if left(s,1) = semicolon Then Exit Function
If InStr(s, semicolon) > 0 Then s = Left(s, InStr(s, semicolon) - 1)
TrimComments = s
End Function
' Removes whatever characters we want to call "noise" from the start
' and end of a string.
function TrimNoise(ByVal s)
rx.Pattern = "^" & noisePattern
s = rx.Replace(s, vbNullString)
rx.Pattern = noisePattern & "$"
s = rx.Replace(s, vbNullString)
TrimNoise = s
End Function
Sub WriteWarning(ByVal line, ByVal data, ByVal comment)
If m_Warn Then
WScript.StdErr.WriteLine "Possible error on line " & line & "."
WScript.StdErr.WriteLine "data: " & data
WScript.StdErr.WriteLine "Comments: " & comment
WScript.StdErr.WriteLine
End If
End Sub
Sub WriteOutput(ByVal s)
If m_Output Then
WScript.Stdout.Writeline s
End If
End Sub
</font></pre>
Edited by - WatercoolerWarrior on 11/27/2004 7:18:18 AM
Edited by - WatercoolerWarrior on 11/27/2004 7:20:04 AM
1 - Make sure you have WSH 5.6 installed; it comes with Windows XP and newer already, or can be downloaded from Microsoft's Scripting Technologies web site.
2 - Save the code to a file with a .vbs extension; for example, flint.vbs.
3. - Run it. You need to explicitly use the WSH console variant (cscript) to execute the script, and redirect input from the file you want to test. So for example, if you saved the file to "C:\My Temp Files\flint.vbs" and want to test
"C:\Program Files\Microsoft Games\Freelancer\DATA\SHIPS\shiparch.ini", you would do this:
<pre><font size=1 face=Courier>cscript "C:\My Temp Files\flint.vbs" < "C:\Program Files\Microsoft Games\Freelancer\DATA\SHIPS\shiparch.ini" </font></pre>
Note that this isn't very useful for testing stock files or FL SDK files; the "errors" it will pick up are either errors Freelancer is theoretically able to handle OK or apparently correct usage (such as the "assertion" lines in navbar.ini - behavior/mesh/event etc.)
<pre><font size=1 face=Courier>
' Parses a decompressed Freelancer INI file looking for possible errors.
' Copyright: This is my work and I hereby place it in the public domain.
Option Explicit
Dim namedArgs: Set namedArgs = WScript.Arguments.Named
' m_Warn controls whether warnings for bad values are shown.
Dim m_Warn: m_Warn = True
If namedArgs.Exists("W" ) and namedArgs("W" ) = False Then
m_Warn = False
End If
' Set this flag if we want good data written to stdout.
Dim m_Output: m_Output = False
If namedArgs.Exists("O" ) Then m_Output = True
' Global declaration of the regex used in procedure TrimNoise().
Dim rx: set rx = New Regexp: rx.Global = True
' This is a quick regex for whitespacish characters. In theory, most should
' never show up in a data segment, but let's be cautious anyway.
' This will also make sure we treat ASCII 160 as a space.
' The NON-noise set is thus the following:
' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO
' PQRSTUVWXYZ[\^_`abcdefghijklmnopqrstuvwxyz{/}~
Const noisePattern = "[\x00-\x20\x7f-\xff+"
'Main processing loop
Do While Not WScript.StdIn.AtEndofStream
Dim originalData: originalData = WScript.StdIn.ReadLine()
Dim data: data = TrimNoise(TrimComments(originalData))
If Len(data) = 0 Then
' This is just a spacing line; pass it on.
WriteOutput vbNullString
ElseIf Left(data, 1) = "[" Then
' Looks like a header
If Right(data, 1) <> Chr(93) Then
' Looks like a malformed header
' Chr(93) is a close bracket; using this to handle LTR forum posting.
WriteWarning WScript.StdIn.Line - 1, originalData, _
"This may be a bad header."
Else
' Looks good; write it.
WriteOutput data
End If
ElseIf Right(data, 1) = Chr(93) Then
' Looks like a malformed header
' Chr(93) is a close bracket; using this to handle LTR forum posting.
WriteWarning WScript.StdIn.Line - 1, originalData, _
"This may be a bad header."
Else
' This looks like a data line. Check for '='.
Dim elements: elements = Split(data, "=" )
Select Case UBound(elements)
Case 0, -1
' Only 1 element. This is apparently anomalous other than in
' \Data\Interface\Baseside\navbar.ini
WriteWarning WScript.StdIn.Line - 1, originalData, _
"No '=' found; may be anomalous value unless in navbar.ini."
' We still write it out since it is possibly OK and since
' Freelancer seems to cope with it OK.
WriteOutput data
Case 1
elements(0) = TrimNoise(0): elements(1) = TrimNoise(1)
if Len(elements(0)) = 0 or Len(elements(1)) = 0 Then
' We are missing a name or a value. This is an error.
WriteWarning WScript.StdIn.Line - 1, originalData, _
"Missing a keyname or a value."
Else
' Looks good; write it out.
WriteOutput Join(elements, " = " )
End If
Case Else
WriteWarning WScript.StdIn.Line - 1, originalData, _
"Extra '=' in data."
End Select
End If
Loop
' End of main processing loop; the rest of this is declarations
' of procedures used in code above.
function TrimComments(ByVal s)
' this is specifically designed to strip extraneous material
' from a decompressed Freelancer Ini file line.
TrimComments = vbNullString
' we leave if a line is empty
If len(s) = 0 Then Exit Function
' we assume there is NO way a semicolon can be meaningful data.
' There is one possible exception; a quoted semicolon in keymap.ini
' could cause a problem; we eventually need to fix this.
' For now, it is probably better to work it this way.
Dim semicolon: semicolon = ";"
if left(s,1) = semicolon Then Exit Function
If InStr(s, semicolon) > 0 Then s = Left(s, InStr(s, semicolon) - 1)
TrimComments = s
End Function
' Removes whatever characters we want to call "noise" from the start
' and end of a string.
function TrimNoise(ByVal s)
rx.Pattern = "^" & noisePattern
s = rx.Replace(s, vbNullString)
rx.Pattern = noisePattern & "$"
s = rx.Replace(s, vbNullString)
TrimNoise = s
End Function
Sub WriteWarning(ByVal line, ByVal data, ByVal comment)
If m_Warn Then
WScript.StdErr.WriteLine "Possible error on line " & line & "."
WScript.StdErr.WriteLine "data: " & data
WScript.StdErr.WriteLine "Comments: " & comment
WScript.StdErr.WriteLine
End If
End Sub
Sub WriteOutput(ByVal s)
If m_Output Then
WScript.Stdout.Writeline s
End If
End Sub
</font></pre>
Edited by - WatercoolerWarrior on 11/27/2004 7:18:18 AM
Edited by - WatercoolerWarrior on 11/27/2004 7:20:04 AM