No worries, I got a script working. It's not exactly elegant or robust but it seems to do what I need.
Code:
Option Explicit
Dim fso
Call WScript.Quit( main() )
' Returns the entire contents of a text file
'''
Function ReadFile(sFilePath)
Const ForReading = 1, AsciiFormat = 0
Dim TextStream
Set TextStream = fso.OpenTextFile(sFilePath, ForReading, False, AsciiFormat)
ReadFile = TextStream.ReadAll()
TextStream.Close
End Function
' Writes sContents to the specified file.
'''
Sub WriteFile(sFilePath, sContents)
Const ForWriting = 2, AsciiFormat = 0
Dim TextStream
Set TextStream = fso.OpenTextFile(sFilePath, ForWriting, True, AsciiFormat)
TextStream.Write sContents
TextStream.Close
End Sub
' Relocates all #includes and #defines to the beginning
' of the source and removes duplicates.
'''
Function PreProcess(sOldSource)
Dim sNewSource, sTokens, sLine
Dim i, rgsLines, rgsArray
Dim dctTokens
Set dctTokens = CreateObject("Scripting.Dictionary")
rgsLines = Split(sOldSource, vbcrlf, -1, 0)
For i = LBound(rgsLines) To UBound(rgsLines)
sLine = Replace(rgsLines(i), " ", "")
sLine = Replace(rgsLines(i), vbTab, "")
If ( Left(sLine, Len("#include")) = "#include" Or _
Left(sLine, Len("#define")) = "#define" ) Then
if (Not dctTokens.Exists(rgsLines(i))) Then dctTokens.Add rgsLines(i), 0
Else
sNewSource = sNewSource & rgsLines(i) & vbcrlf
End If
Next
rgsArray = dctTokens.Keys
For i = LBound(rgsArray) To UBound(rgsArray)
sTokens = sTokens & rgsArray(i) & vbcrlf
Next
PreProcess = sTokens & sNewSource
End Function
' Removes comments from the source
'''
Function RemoveComments(sOldSource)
Dim sNewSource, regEx
Set regEx = CreateObject("VBScript.RegExp")
regEx.Global = True
regEx.IgnoreCase = True
' Deal with /* */ comments that have a line to themselves.
regEx.Pattern = "\r\n[\t ]*/\*(.|[\r\n])*?\*/[\t ]*\r\n"
sNewSource = regEx.Replace(sOldSource, vbcrlf)
' Deal with /* */ comments that share the line.
regEx.Pattern = "/\*(.|[\r\n])*?\*/"
sNewSource = regEx.Replace(sNewSource, "")
' Deal with // comments that have a line to themselves.
regEx.Pattern = "\r\n[\t ]*//[^\r]*\r\n"
sNewSource = regEx.Replace(sNewSource, vbcrlf)
' Deal with // comments that share a line
regEx.Pattern = "//[^\r]*"
sNewSource = regEx.Replace(sNewSource, "")
' Remove double white lines
regEx.Pattern = "\r\n[\t \r\n]*\r\n"
sNewSource = regEx.Replace(sNewSource, vbcrlf & vbcrlf)
' Remove line ending white space
regEx.Pattern = "[\t ]*\r\n"
sNewSource = regEx.Replace(sNewSource, vbcrlf)
RemoveComments = sNewSource
End Function
Function main()
Const EXIT_SUCCESS = 0, EXIT_FAILURE = 1
Dim sArg, sSource, sOldSource, sNewSource
Set fso = CreateObject("Scripting.FileSystemObject")
For Each sArg In WScript.Arguments
sOldSource = sOldSource & vbCrLf & "@@@<<@@ ----- " & _
fso.GetFileName(sArg) & " ----- @@>>@@@" & _
vbCrLf & ReadFile(sArg)
Next
sNewSource = PreProcess(sOldSource)
sNewSource = RemoveComments(sNewSource)
sNewSource = Replace(sNewSource, "@@@<<@@", "/*")
sNewSource = Replace(sNewSource, "@@>>@@@", "*/")
Call WriteFile("output.c", sNewSource)
main = EXIT_SUCCESS
End Function
If anyone actually uses this:
- You'll probably want to specify the filenames in an array so you can decide on order.
- It is possible that the board has stuffed up some of the regular expressions.
- There are many things it doesn't handle - such as multi line defines.