223 lines
4.6 KiB
C++
223 lines
4.6 KiB
C++
|
|
||
|
// ToLuaDoxy.cpp
|
||
|
|
||
|
// Implements the main app entrypoint
|
||
|
|
||
|
#include "Globals.h"
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
typedef std::vector<AString> AStrings;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
class cProcessor
|
||
|
{
|
||
|
public:
|
||
|
cProcessor(const AString & a_FileOut) :
|
||
|
m_Out(a_FileOut.c_str(), std::ios::out),
|
||
|
m_IsInToLua(false),
|
||
|
m_IsInComment(false)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
|
||
|
bool IsGood(void) const
|
||
|
{
|
||
|
return !m_Out.fail();
|
||
|
}
|
||
|
|
||
|
|
||
|
void ProcessFile(const AString & a_FileIn)
|
||
|
{
|
||
|
std::ifstream In(a_FileIn.c_str());
|
||
|
if (In.fail())
|
||
|
{
|
||
|
std::cerr << "Cannot open input file " << a_FileIn << "." << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
while (!In.eof())
|
||
|
{
|
||
|
AString Line;
|
||
|
std::getline(In, Line);
|
||
|
PushLine(Line);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
std::ofstream m_Out;
|
||
|
bool m_IsInToLua; ///< Set to true if inside a tolua_begin .. tolua_end block
|
||
|
bool m_IsInComment; ///< Set to true if previous line has started a multiline comment; only outside tolua blocks
|
||
|
AString m_LastComment; ///< Accumulator for a multiline comment preceding a tolua block
|
||
|
|
||
|
|
||
|
void PushLine(const AString & a_Line)
|
||
|
{
|
||
|
if (m_IsInToLua)
|
||
|
{
|
||
|
// Inside a tolua block
|
||
|
if (TrimString(a_Line) == "// tolua_end")
|
||
|
{
|
||
|
// End of a tolua block
|
||
|
m_IsInToLua = false;
|
||
|
return;
|
||
|
}
|
||
|
m_Out << a_Line << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (m_IsInComment)
|
||
|
{
|
||
|
// Inside a multiline comment block, outside of a tolua block; accumulate m_LastComment
|
||
|
m_LastComment += a_Line + "\n";
|
||
|
m_IsInComment = (a_Line.find("*/") == AString::npos);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
AString Trimmed(TrimString(a_Line));
|
||
|
|
||
|
if (Trimmed == "// tolua_begin")
|
||
|
{
|
||
|
// Beginning of a tolua block
|
||
|
m_IsInToLua = true;
|
||
|
if (!m_LastComment.empty())
|
||
|
{
|
||
|
m_Out << m_LastComment << std::endl;
|
||
|
m_LastComment.clear();
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
size_t CommentBegin = a_Line.find("/*");
|
||
|
if (CommentBegin != AString::npos)
|
||
|
{
|
||
|
m_IsInComment = (a_Line.find("*/", CommentBegin) == AString::npos);
|
||
|
m_LastComment = a_Line;
|
||
|
}
|
||
|
|
||
|
size_t ExportIdx = a_Line.find("// tolua_export");
|
||
|
if (ExportIdx != AString::npos)
|
||
|
{
|
||
|
// Single-line tolua block
|
||
|
|
||
|
// Strip the export comment and right-trim the line:
|
||
|
AString Stripped(a_Line.substr(0, ExportIdx));
|
||
|
int End = Stripped.length() - 1;
|
||
|
while ((End > 0) && (Stripped[End] <= 32))
|
||
|
{
|
||
|
End--;
|
||
|
}
|
||
|
Stripped.erase(End + 1);
|
||
|
|
||
|
if (!m_LastComment.empty())
|
||
|
{
|
||
|
m_Out << m_LastComment << std::endl;
|
||
|
m_LastComment.clear();
|
||
|
}
|
||
|
m_Out << Stripped << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (!m_IsInComment)
|
||
|
{
|
||
|
m_LastComment.clear();
|
||
|
}
|
||
|
}
|
||
|
} ;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/** Parses the specified package file into a list of $cfile-included files and all the other contents
|
||
|
Returns true if successful.
|
||
|
Returns false and prints error if unsuccessful
|
||
|
*/
|
||
|
bool ParsePackageFile(const AString & a_FileName, AStrings & a_CFiles, AStrings & a_DirectContentsLines)
|
||
|
{
|
||
|
std::ifstream PkgFile(a_FileName.c_str());
|
||
|
if (PkgFile.fail())
|
||
|
{
|
||
|
std::cerr << "Cannot open the package file " << a_FileName << "." << std::endl;
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
while (!PkgFile.eof())
|
||
|
{
|
||
|
AString Line;
|
||
|
std::getline(PkgFile, Line);
|
||
|
Line = TrimString(Line);
|
||
|
if (strncmp(Line.c_str(), "$cfile \"", 8) == 0)
|
||
|
{
|
||
|
a_CFiles.push_back(Line.substr(8, Line.length() - 9));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
a_DirectContentsLines.push_back(Line);
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/// Processes the specified input header file into the output file
|
||
|
void ProcessCFile(const AString & a_CFileIn, const AString & a_CFileOut)
|
||
|
{
|
||
|
cProcessor p(a_CFileOut);
|
||
|
if (!p.IsGood())
|
||
|
{
|
||
|
std::cerr << "Cannot open output file " << a_CFileOut << "." << std::endl;
|
||
|
return;
|
||
|
}
|
||
|
p.ProcessFile(a_CFileIn);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int main(int argc, char * argv[])
|
||
|
{
|
||
|
AString BaseDir = (argc > 1) ? argv[1] : ".";
|
||
|
AString OutDir = (argc > 2) ? argv[2] : "Out";
|
||
|
|
||
|
// Create the output directory:
|
||
|
#ifdef _WIN32
|
||
|
CreateDirectory(OutDir.c_str(), NULL);
|
||
|
#else
|
||
|
mkdir(OutDir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
|
||
|
#endif
|
||
|
|
||
|
// Parse the package file
|
||
|
AStrings CFiles;
|
||
|
AStrings DirectLines;
|
||
|
if (!ParsePackageFile(Printf("%s/AllToLua.pkg", BaseDir.c_str()), CFiles, DirectLines))
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// Process header files:
|
||
|
for (AStrings::const_iterator itr = CFiles.begin(), end = CFiles.end(); itr != end; ++itr)
|
||
|
{
|
||
|
static int cnt = 0;
|
||
|
AString In = Printf("%s/%s", BaseDir.c_str(), itr->c_str());
|
||
|
AString Out = Printf("%s/%04x.h", OutDir.c_str(), cnt++);
|
||
|
ProcessCFile(In, Out);
|
||
|
} // for itr - CFiles[]
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|