- Yasaklandı
- #1
Banlı Üye
defines.h yapıp bu kodu yapıştırın :
main.cpp kodu :
Kod:
#ifndef __DEFINES_H_INCLUDED__
#define __DEFINES_H_INCLUDED__
#if defined (_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#include <Windows.h>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <regex>
#include <sstream>
#include <string>
/**
*
* Regular expressions used to locate information.
*
*/
const std::wregex g_vRegexInterface(L"^DECLARE_INTERFACE_\\(([a-zA-Z0-9]+), IUnknown\\)$");
const std::wregex g_vRegexFunctions(L"^[\\s]+?STDMETHOD\\(([a-zA-Z0-9]+)\\)\\((.*)\\) PURE;$|^[\\s]+?STDMETHOD_\\(([a-zA-Z0-9]+)[,\\s]+?([a-zA-Z0-9]+)\\)\\((.*)\\) PURE;$");
/**
*
* Regular expression iterator ends.
*
*/
const std::wsregex_iterator g_vRegexIteratorEnd;
const std::wsregex_token_iterator g_vRegexTokenIteratorEnd;
/**
*
* Function entry structure.
*
*/
typedef struct _FUNCTION_ENTRY {
std::wstring Parent;
std::wstring RawFunction;
std::wstring Return;
std::wstring Function;
std::wstring RawArguments;
std::wstring FixedArguments;
} functionentry_t;
/**
*
* Base interface header template.
*
*/
const wchar_t* g_vHeaderTemplate[] =
{
L"",
L"/**",
L" * new{INTERFACE}.h - {INTERFACE} Wrapper Header",
L" *",
L" * This file was generated using d3dxgen!atom0s.cpp",
L" * (c) 2011-2013 atom0s [[email protected]]",
L" */",
L"",
L"#pragma once",
L"",
L"#ifndef __{INTERFACEUPPER}_H_INCLUDED__",
L"#define __{INTERFACEUPPER}_H_INCLUDED__",
L"",
L"#include <Windows.h>",
L"#include <d3d9.h>",
L"",
L"interface new{INTERFACE} : public {INTERFACE}",
L"{",
L"public:",
L"{CLASS_DATA}",
L"",
L"public:",
L" new{INTERFACE}( {INTERFACE}** ppOrigInterface );",
L" virtual ~new{INTERFACE}( void );",
L"",
L"private:",
L" {INTERFACE}* m_vOrigInterface;",
L"};",
L"",
L"#endif // __{INTERFACEUPPER}_H_INCLUDED__"
};
/**
*
* Base interface source template.
*
*/
const wchar_t* g_vSourceTemplate[] =
{
L"",
L"/**",
L" * new{INTERFACE}.cpp - {INTERFACE} Wrapper Source File",
L" *",
L" * This file was generated using d3dxgen!atom0s.cpp",
L" * (c) 2011-2013 atom0s [[email protected]]",
L" */",
L"",
L"#include \"new{INTERFACE}.h\"",
L"",
L"new{INTERFACE}::new{INTERFACE}( {INTERFACE}** ppOrigInterface )",
L"{",
L" this->m_vOrigInterface = *ppOrigInterface;",
L"}",
L"new{INTERFACE}::~new{INTERFACE}( void )",
L"{",
L"}",
L""
};
/**
*
* Function definition template (header file).
*
*/
const std::wstring g_vFunctionTemplate = L"virtual __declspec( nothrow ) {RETURN} __stdcall {FUNCTION}({ARGUMENTS});";
/**
*
* Function definition templates (source file).
*
*/
const std::wstring g_vSouceFunctionTemplate = L"{RETURN} new{INTERFACE}::{FUNCTION}( {ARGUMENTS} )";
const std::wstring g_vReturnTemplateVoid = L"m_vOrigInterface->{FUNCTION}( {ARGUMENTS_CALL} );";
const std::wstring g_vReturnTemplate = L"return " + g_vReturnTemplateVoid;
/**
* Wide String Replace
*
* Used for easily modifing template strings with tokens.
*/
static inline DWORD WStrRep(std::wstring& wstrInput, const std::wstring& wstrWhat, const std::wstring& wstrWith)
{
size_t nPosition = wstrInput.find(wstrWhat, 0);
int nMatches = 0;
while (nPosition != std::wstring::npos)
{
wstrInput.replace(nPosition, wstrWhat.size(), wstrWith);
nPosition = wstrInput.find(wstrWhat, nPosition);
nMatches++;
}
return nMatches;
}
/**
* Converts the input string to lower-case.
*/
static inline std::wstring& WStrLower(std::wstring& wstrInput)
{
std::transform(wstrInput.begin(), wstrInput.end(), wstrInput.begin(), ::tolower);
return wstrInput;
}
/**
* Converts the input string to upper-case.
*/
static inline std::wstring& WStrUpper(std::wstring& wstrInput)
{
std::transform(wstrInput.begin(), wstrInput.end(), wstrInput.begin(), ::toupper);
return wstrInput;
}
/**
* Trim
*
* Removes whitespace from the strings beginning/end.
*/
static inline std::wstring& trim(std::wstring& input)
{
input.erase(0, input.find_first_not_of(L' '));
input.erase(input.find_last_not_of(L' ') + 1);
return input;
}
/**
* RemoveSpecialChars
*
* Removes special characters from the input string.
*/
static inline std::wstring& RemoveSpecialChars(std::wstring& input)
{
std::wstring wstrNewString;
static const wchar_t wszInvalidChars[] = { L'*', L'&' };
for (unsigned int x = 0; x < input.size(); x++)
{
if (input.at(x) != wszInvalidChars[0] &&
input.at(x) != wszInvalidChars[1])
wstrNewString += input.at(x);
}
input = wstrNewString;
return input;
}
/**
* BuildFunctionCall
*
* Builds a function based on the input information given.
*/
static inline std::wstring BuildFunctionCall(functionentry_t& f)
{
//
// Invalid Argument Variables
//
static const std::wstring wstrInvalidArgument = L"INVALID_ARG";
int nInvalidCount = 0;
//
// Parse for function arguments..
//
std::list< std::wstring > listArguments;
std::wstring::size_type start = 0;
std::wstring::size_type end = f.RawArguments.find(L",");
while (end != std::wstring::npos)
{
listArguments.push_back(trim(f.RawArguments.substr(start, end - start)));
start = end + 1;
end = f.RawArguments.find(L",", start);
}
listArguments.push_back(trim(f.RawArguments.substr(start)));
//
// Parse for argument variables...
//
std::list< std::wstring > listFuncArgs;
for (std::list< std::wstring >::iterator iter = listArguments.begin(), iterend = listArguments.end(); iter != iterend; ++iter)
{
// Cleanup argument whitespace..
const std::wstring wstrRawArgument = *iter;
std::wstring wstrArgument = trim(std::wstring(*iter));
// Determine space count..
std::wstring::size_type numSpaces = std::count_if(wstrArgument.begin(), wstrArgument.end(),
[](const wchar_t wch) { return (wch == L' '); }
);
// Determine how many keywords we have (ex. const, class, struct)
std::wstring::size_type numKeywords = 0;
numKeywords += (WStrLower(wstrArgument).find(L"class ") == -1) ? 0 : 1;
numKeywords += (WStrLower(wstrArgument).find(L"const ") == -1) ? 0 : 1;
numKeywords += (WStrLower(wstrArgument).find(L"struct ") == -1) ? 0 : 1;
// Are we a normal argument with no keywords?
if (numSpaces == 1 && numKeywords == 0)
{
std::wstring wstrArg = wstrRawArgument.substr(wstrRawArgument.find_last_of(L" ") + 1);
listFuncArgs.push_back(RemoveSpecialChars(wstrArg));
}
// Are we an argument with keywords?
else if (numSpaces >= 2 && numKeywords > 0)
{
std::wstring wstrArg = wstrRawArgument.substr(wstrRawArgument.find_last_of(L" ") + 1);
listFuncArgs.push_back(RemoveSpecialChars(wstrArg));
}
// Is there a space between an astrisk?
else if (numSpaces == 2 && numKeywords == 0)
{
std::wstring wstrArg = wstrRawArgument.substr(wstrRawArgument.find_last_of(L" ") + 1);
listFuncArgs.push_back(RemoveSpecialChars(wstrArg));
}
else if ((numSpaces == 1 || numSpaces == 2) && numKeywords > 0)
{
++nInvalidCount;
// Create a temp argument for this invalid arg.
std::wstringstream wstrStreamFuncArg(wstrInvalidArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
wstrStreamFuncArg << (nInvalidCount - 1);
listFuncArgs.push_back(wstrStreamFuncArg.str());
// Fix the original functions argument list..
std::wstringstream wstrStreamArg(wstrRawArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
wstrStreamArg << L" " << wstrInvalidArgument << (nInvalidCount - 1);
*iter = wstrStreamArg.str();
}
// Are we just the word void?
else if (numSpaces == 0 && numKeywords == 0 && wstrArgument.length() == 4 && wstrArgument == L"void")
{
// Don't push anything or we will create invalid calls..
}
// Are we just a single word..
else if (numSpaces == 0 && numKeywords == 0 && wstrArgument.length() > 0)
{
++nInvalidCount;
// Create a temp argument for this invalid arg.
std::wstringstream wstrStreamFuncArg(wstrInvalidArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
wstrStreamFuncArg << (nInvalidCount - 1);
listFuncArgs.push_back(wstrStreamFuncArg.str());
// Fix the original functions argument list..
std::wstringstream wstrStreamArg(wstrRawArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
wstrStreamArg << L" " << wstrInvalidArgument << (nInvalidCount - 1);
*iter = wstrStreamArg.str();
}
// Completely invalid argument not recognized yet..
else
{
std::wcout << L"=================================================" << std::endl;
std::wcout << L"Could not find a valid argument while parsing: " << f.Function << L", debug info:" << std::endl;
std::wcout << L"=================================================" << std::endl;
std::wcout << f.RawFunction << std::endl;
std::wcout << L" Argument: " << wstrRawArgument << std::endl;
std::wcout << L" Space count: " << numSpaces << std::endl << L" Keyword count: " << numKeywords << std::endl;
std::wcout << L" Arguments: " << f.RawArguments << std::endl;
}
}
//
// Build the full function with parsed data..
//
std::wstringstream wstrFullFunction;
wstrFullFunction << f.Return << L" __stdcall new{INTERFACE}::" << f.Function << L"( ";
int nCommaCount = listArguments.size() - 1;
std::for_each(listArguments.begin(), listArguments.end(),
[&](const std::wstring& wstr)
{
wstrFullFunction << wstr;
f.FixedArguments += wstr;
if (nCommaCount)
{
wstrFullFunction << L", ";
f.FixedArguments += L", ";
}
--nCommaCount;
});
wstrFullFunction << L" )" << std::endl << L"{" << std::endl;
if (f.Return == L"void")
wstrFullFunction << L" m_vOrigInterface->" << f.Function << L"(";
else
wstrFullFunction << L" return m_vOrigInterface->" << f.Function << L"( ";
nCommaCount = listFuncArgs.size() - 1;
std::for_each(listFuncArgs.begin(), listFuncArgs.end(),
[&](const std::wstring& wstr)
{
wstrFullFunction << wstr;
if (nCommaCount)
wstrFullFunction << L", ";
--nCommaCount;
});
wstrFullFunction << L" );" << std::endl << L"}" << std::endl;
return wstrFullFunction.str();
}
#endif // __DEFINES_H_INCLUDED__
main.cpp kodu :
Kod:
#include <Windows.h>
#include "defines.h"
#include <cmath>
#include <functional>
#include <list>
#include <map>
int __cdecl main(int argc, wchar_t* argv[])
{
// Ensure a target header was given..
if (argc != 2 || strlen((char*)argv[1]) == 0)
{
std::wcout << L"ERROR: No input file was given!" << std::endl;
std::wcout << L"Usage: dxgen.exe [input_file]" << std::endl;
return 0;
}
// Attempt to load target header file..
std::wifstream wifs((char*)argv[1]);
if (!wifs.is_open())
{
std::wcout << L"ERROR: Failed to open target file, " << (char*)argv[1] << std::endl;
return 0;
}
// Read and close file..
std::wstring wstrFileData((std::istreambuf_iterator< wchar_t >(wifs)), std::istreambuf_iterator< wchar_t >());
wifs.close();
// Scan and dump all interfaces..
std::wcout << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::wcout << L"Parsing header file for interfaces..." << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::map< std::wstring, std::wstring > mapInterfaces;
for (std::wsregex_iterator iter_interfaces(wstrFileData.begin(), wstrFileData.end(), g_vRegexInterface); iter_interfaces != g_vRegexIteratorEnd; ++iter_interfaces)
{
// Copy full interface from file contents..
int nStartPos = iter_interfaces->position();
int nBracePos = (wstrFileData.find(L"}", nStartPos)) + 2;
std::wstring wstrInterface(wstrFileData.substr(nStartPos, (nBracePos - nStartPos)));
// Store this interface..
mapInterfaces[(*iter_interfaces)[1]] = wstrInterface;
std::wcout << L"Found interface: " << (*iter_interfaces)[1] << std::endl;
}
// Assure we found some interfaces..
if (mapInterfaces.size() == 0)
{
std::wcout << L"ERROR: Failed to parse for any interfaces." << std::endl;
return 0;
}
// Parse each interface for functions..
std::wcout << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::wcout << L"Parsing interfaces for functions..." << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::map< std::pair< std::wstring, std::wstring >, std::list< functionentry_t > > mapFunctions;
std::for_each(mapInterfaces.begin(), mapInterfaces.end(),
[&](const std::pair< std::wstring, std::wstring >& p)
{
std::wcout << L"Parsing interface: " << p.first << std::endl;
std::list< functionentry_t > listFunctions;
for (std::wsregex_iterator iter_functions(p.second.begin(), p.second.end(), g_vRegexFunctions); iter_functions != g_vRegexIteratorEnd; ++iter_functions)
{
int nGroups = std::count_if(iter_functions->begin(), iter_functions->end(), [](const std::wssub_match& smatch) { return (smatch.matched == true); });
// Create function entry..
functionentry_t functionEntry;
functionEntry.RawFunction = (*iter_functions)[0].str();
functionEntry.Return = (nGroups == 3) ? L"HRESULT" : (*iter_functions)[3].str();
functionEntry.Function = (nGroups == 3) ? (*iter_functions)[1].str() : (*iter_functions)[4].str();
functionEntry.RawArguments = (nGroups == 3) ? (*iter_functions)[2].str() : (*iter_functions)[5].str();
// Cleanup unneeded macros..
WStrRep(functionEntry.RawArguments, L"THIS_", L"");
WStrRep(functionEntry.RawArguments, L"THIS", L"void");
// Cleanup double-spaces..
WStrRep(functionEntry.RawArguments, L" ", L" ");
// Store this function entry..
listFunctions.push_back(functionEntry);
std::wcout << L" Found function: " << functionEntry.Function << std::endl;
}
// Store functions.
mapFunctions[p] = listFunctions;
});
// Ensure all maps have functions..
std::wcout << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::wcout << L"Validating interface function lists..." << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::map< std::pair< std::wstring, std::wstring >, std::list< functionentry_t > >::iterator iter_func = mapFunctions.begin();
while (iter_func != mapFunctions.end())
{
std::wcout << L"Validating interface: " << (*iter_func).first.first << " ... ";
if ((*iter_func).second.size() == 0)
{
std::wcout << L"Invalid! Removing.." << std::endl;
mapFunctions.erase(iter_func++);
}
else
{
std::wcout << L"Ok!" << std::endl;
++iter_func;
}
}
// Prepare path information..
wchar_t wszCurrentDirectory[MAX_PATH] = { 0 };
GetCurrentDirectory(MAX_PATH, wszCurrentDirectory);
std::wstring wstrOutputPath = std::wstring(wszCurrentDirectory) + L"\\includes\\";
if (GetFileAttributes(wstrOutputPath.c_str()) == 0xFFFFFFFF)
CreateDirectory(wstrOutputPath.c_str(), NULL);
// Create source files for each found interface..
std::wcout << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::wcout << L"Creating source files for found interfaces..." << std::endl;
std::wcout << L"=====================================================" << std::endl;
for (auto iter = mapFunctions.begin(), iterend = mapFunctions.end(); iter != iterend; ++iter)
{
std::wcout << L"Creating source file: " << (*iter).first.first << L".cpp" << std::endl;
// Iterate and create each function body..
std::list< std::wstring > listFuncBodies;
for (auto fiter = (*iter).second.begin(), fiterend = (*iter).second.end(); fiter != fiterend; ++fiter)
{
std::wcout << L" Building function: " << (*fiter).Function << std::endl;
std::wstring wstrFunctionBody = BuildFunctionCall(*fiter);
WStrRep(wstrFunctionBody, L"{INTERFACE}", (*iter).first.first);
listFuncBodies.push_back(wstrFunctionBody);
}
// Create our output file..
std::wofstream wofs(std::wstring(wstrOutputPath + L"new" + (*iter).first.first + L".cpp"), std::ios_base::binary);
if (!wofs.is_open())
{
std::wcout << L"Failed to create file: " << (*iter).first.first << L".cpp" << std::endl;
}
else
{
std::wstring wstrSourceFile;
std::for_each(g_vSourceTemplate, g_vSourceTemplate + (sizeof(g_vSourceTemplate) / sizeof(g_vSourceTemplate[0])),
[&](const std::wstring& wstr)
{
std::wstring wstrLine = wstr;
std::wstring wstrLower = (*iter).first.first;
std::wstring wstrUpper = (*iter).first.first;
std::transform(wstrLower.begin(), wstrLower.end(), wstrLower.begin(), ::tolower);
std::transform(wstrUpper.begin(), wstrUpper.end(), wstrUpper.begin(), ::toupper);
WStrRep(wstrLine, L"{INTERFACE}", (*iter).first.first);
WStrRep(wstrLine, L"{INTERFACELOWER}", wstrLower);
WStrRep(wstrLine, L"{INTERFACEUPPER}", wstrUpper);
wstrSourceFile += wstrLine + L"\r\n";
});
wofs << wstrSourceFile;
std::ostream_iterator< std::wstring, wchar_t > ositer(wofs, L"\r\n");
std::copy(listFuncBodies.begin(), listFuncBodies.end(),
std::ostream_iterator< std::wstring, wchar_t >(wofs, L"\r\n")
);
wofs.close();
}
}
// Create header files for each found interface..
std::wcout << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::wcout << L"Creating header files for found interfaces..." << std::endl;
std::wcout << L"=====================================================" << std::endl;
std::for_each(mapFunctions.begin(), mapFunctions.end(),
[&](const std::pair< std::pair< std::wstring, std::wstring >, std::list< functionentry_t > >& p)
{
std::wcout << L"Creating header file: " << p.first.first << L".h ... ";
std::wofstream wofs(std::wstring(wstrOutputPath + L"new" + p.first.first + L".h"), std::ios_base::binary);
if (!wofs.is_open())
{
std::wcout << L"Failed!" << std::endl;
}
else
{
// Generate header file..
std::wstring wstrHeader;
std::for_each(g_vHeaderTemplate, g_vHeaderTemplate + (sizeof(g_vHeaderTemplate) / sizeof(g_vHeaderTemplate[0])),
[&](const std::wstring& wstr)
{
std::wstring wstrLine = wstr;
std::wstring wstrLower = p.first.first;
std::wstring wstrUpper = p.first.first;
std::transform(wstrLower.begin(), wstrLower.end(), wstrLower.begin(), ::tolower);
std::transform(wstrUpper.begin(), wstrUpper.end(), wstrUpper.begin(), ::toupper);
WStrRep(wstrLine, L"{INTERFACE}", p.first.first);
WStrRep(wstrLine, L"{INTERFACELOWER}", wstrLower);
WStrRep(wstrLine, L"{INTERFACEUPPER}", wstrUpper);
wstrHeader += wstrLine + L"\r\n";
});
// Generate class data..
std::wstring wstrClassData;
std::for_each(p.second.begin(), p.second.end(),
[&](const functionentry_t& f)
{
std::wstring wstrReturn = f.Return;
std::wstring wstrFunction = f.Function;
std::wstring wstrArguments = f.FixedArguments;
WStrRep(wstrArguments, L"THIS_", L"");
WStrRep(wstrArguments, L"THIS", L"");
trim(wstrArguments);
if (wstrArguments.size() == 0)
wstrArguments = L"void";
wstrArguments.insert(wstrArguments.cbegin(), L' ');
wstrArguments.insert(wstrArguments.cend(), L' ');
std::wstring wstrFullFunction = g_vFunctionTemplate;
WStrRep(wstrFullFunction, L"{RETURN}", wstrReturn);
WStrRep(wstrFullFunction, L"{FUNCTION}", wstrFunction);
WStrRep(wstrFullFunction, L"{ARGUMENTS}", wstrArguments);
wstrClassData += L" " + wstrFullFunction + L"\r\n";
});
WStrRep(wstrHeader, L"{CLASS_DATA}", wstrClassData);
wofs << wstrHeader;
wofs.close();
std::wcout << L"Ok!" << std::endl;
}
});
std::cin.sync();
std::cin.ignore();
return 0;
}