Has anyone got a script to turn a multi-file C source into a single file? Just asking, before I reinvent the wheel.
- Remove duplicate #defines
- Remove duplicate #includes
- Remove comments
Thanks.
Printable View
Has anyone got a script to turn a multi-file C source into a single file? Just asking, before I reinvent the wheel.
- Remove duplicate #defines
- Remove duplicate #includes
- Remove comments
Thanks.
Not sure what you mean by 'remove' duplicates?
gcc -E prog.c
This removes comments, expands includes and replaces #defines
gcc -MM prog.c
This outputs a list of header files which prog.c depends on.
Don't see why anyone would want to do such a thing.
I have a library, which of course, is split into multiple modules. For simplicity of use and distribution I want to make it available as a single source file.
For example, if we have:
Then I want this as the result (all in one file):Code:- File 1:
#define UNICODE
#include <windows.h>
#include <stdio.h>
void function(void) {
/* Some comment */
some code;
}
- File 2:
#define UNICODE
#include <windows.h>
#include <something.h>
void function2(int i) {
while(i++) < 10000 printf("hello");
/* another comment */
}
Note: duplicate includes and defines gone, comments gone and all in one file.Code:#define UNICODE
#include <windows.h>
#include <stdio.h>
#include <something.h>
void function(void) {
some code;
}
void function2(int i) {
while(i++) < 10000 printf("hello");
}
Salem:
Thanks for the ideas but I don't wish to expand includes or resolve defines.
I have made some progress on a rough script.
No worries, I got a script working. It's not exactly elegant or robust but it seems to do what I need.
If anyone actually uses this: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
- 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.