Registration Code (Part 1): w%kQ6
Registration Code (Part 2): b<#$1[*(cw~
In order to register on this forum, you must use the codes above. Combine them into one code (copy paste).

Direct3D Wrapper Generator

Programming topics that relate to the C/C++ languages.
Post Reply
User avatar
atom0s
Site Admin
Posts: 401
Joined: Sun Jan 04, 2015 11:23 pm
Location: 127.0.0.1
Contact:

Direct3D Wrapper Generator

Post by atom0s » Fri Jan 09, 2015 10:07 am

Some old code I wrote a while back to generate wrappers for Direct3D related headers. (Direct3D8 and Direct3D9)

Some notes about this:
  • The code is old and shitty; I'm not really looking for feedback. Just sharing it.
  • The generation has been tested for d3d8.h, d3d9.h and dinput.h
  • Not all generations are 100% perfect.
When a generation fails to work, the app will print out to you what it failed to parse/generate for.

Basically the biggest faults in the headers are when the functions do not contain arguments (such as much of the DirectInput header). The parser will attempt to automatically assign generic argument names for these occurrences.

defines.h
  1. /**
  2. * dxgen - (c) 2011-2013 atom0s [atom0s@live.com]
  3. *
  4. * Slim wrapper generator for Direct3D9. Parses d3d9.h for
  5. * interfaces and generates wrappers for each interface
  6. * found.
  7. *
  8. */
  9.  
  10. #ifndef __DEFINES_H_INCLUDED__
  11. #define __DEFINES_H_INCLUDED__
  12.  
  13. #if defined (_MSC_VER) && (_MSC_VER >= 1020)
  14. #pragma once
  15. #endif
  16.  
  17. #include <Windows.h>
  18. #include <fstream>
  19. #include <iostream>
  20. #include <list>
  21. #include <map>
  22. #include <regex>
  23. #include <sstream>
  24. #include <string>
  25.  
  26. /**
  27.  *
  28.  * Regular expressions used to locate information.
  29.  *
  30.  */
  31. const std::wregex g_vRegexInterface(L"^DECLARE_INTERFACE_\\(([a-zA-Z0-9]+), IUnknown\\)$");
  32. 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;$");
  33.  
  34. /**
  35.  *
  36.  * Regular expression iterator ends.
  37.  *
  38.  */
  39. const std::wsregex_iterator         g_vRegexIteratorEnd;
  40. const std::wsregex_token_iterator   g_vRegexTokenIteratorEnd;
  41.  
  42. /**
  43.  *
  44.  * Function entry structure.
  45.  *
  46.  */
  47. typedef struct _FUNCTION_ENTRY {
  48.     std::wstring Parent;
  49.     std::wstring RawFunction;
  50.     std::wstring Return;
  51.     std::wstring Function;
  52.     std::wstring RawArguments;
  53.     std::wstring FixedArguments;
  54. } functionentry_t;
  55.  
  56. /**
  57.  *
  58.  * Base interface header template.
  59.  *
  60.  */
  61. const wchar_t* g_vHeaderTemplate[] =
  62. {
  63.     L"",
  64.     L"/**",
  65.     L" * new{INTERFACE}.h - {INTERFACE} Wrapper Header",
  66.     L" *",
  67.     L" * This file was generated using d3dxgen!atom0s.cpp",
  68.     L" * (c) 2011-2013 atom0s [atom0s@live.com]",
  69.     L" */",
  70.     L"",
  71.     L"#pragma once",
  72.     L"",
  73.     L"#ifndef __{INTERFACEUPPER}_H_INCLUDED__",
  74.     L"#define __{INTERFACEUPPER}_H_INCLUDED__",
  75.     L"",
  76.     L"#include <Windows.h>",
  77.     L"#include <d3d9.h>",
  78.     L"",
  79.     L"interface new{INTERFACE} : public {INTERFACE}",
  80.     L"{",
  81.     L"public:",
  82.     L"{CLASS_DATA}",
  83.     L"",
  84.     L"public:",
  85.     L"   new{INTERFACE}( {INTERFACE}** ppOrigInterface );",
  86.     L"   virtual ~new{INTERFACE}( void );",
  87.     L"",
  88.     L"private:",
  89.     L"   {INTERFACE}* m_vOrigInterface;",
  90.     L"};",
  91.     L"",
  92.     L"#endif // __{INTERFACEUPPER}_H_INCLUDED__"
  93. };
  94.  
  95.  
  96. /**
  97.  *
  98.  * Base interface source template.
  99.  *
  100.  */
  101. const wchar_t* g_vSourceTemplate[] =
  102. {
  103.     L"",
  104.     L"/**",
  105.     L" * new{INTERFACE}.cpp - {INTERFACE} Wrapper Source File",
  106.     L" *",
  107.     L" * This file was generated using d3dxgen!atom0s.cpp",
  108.     L" * (c) 2011-2013 atom0s [atom0s@live.com]",
  109.     L" */",
  110.     L"",
  111.     L"#include \"new{INTERFACE}.h\"",
  112.     L"",
  113.     L"new{INTERFACE}::new{INTERFACE}( {INTERFACE}** ppOrigInterface )",
  114.     L"{",
  115.     L"    this->m_vOrigInterface = *ppOrigInterface;",
  116.     L"}",
  117.     L"new{INTERFACE}::~new{INTERFACE}( void )",
  118.     L"{",
  119.     L"}",
  120.     L""
  121. };
  122.  
  123. /**
  124.  *
  125.  * Function definition template (header file).
  126.  *
  127.  */
  128. const std::wstring g_vFunctionTemplate = L"virtual __declspec( nothrow ) {RETURN} __stdcall {FUNCTION}({ARGUMENTS});";
  129.  
  130. /**
  131.  *
  132.  * Function definition templates (source file).
  133.  *
  134.  */
  135. const std::wstring g_vSouceFunctionTemplate = L"{RETURN} new{INTERFACE}::{FUNCTION}( {ARGUMENTS} )";
  136. const std::wstring g_vReturnTemplateVoid = L"m_vOrigInterface->{FUNCTION}( {ARGUMENTS_CALL} );";
  137. const std::wstring g_vReturnTemplate = L"return " + g_vReturnTemplateVoid;
  138.  
  139. /**
  140.  * Wide String Replace
  141.  *
  142.  * Used for easily modifing template strings with tokens.
  143.  */
  144. static inline DWORD WStrRep(std::wstring& wstrInput, const std::wstring& wstrWhat, const std::wstring& wstrWith)
  145. {
  146.     size_t  nPosition = wstrInput.find(wstrWhat, 0);
  147.     int     nMatches = 0;
  148.  
  149.     while (nPosition != std::wstring::npos)
  150.     {
  151.         wstrInput.replace(nPosition, wstrWhat.size(), wstrWith);
  152.         nPosition = wstrInput.find(wstrWhat, nPosition);
  153.         nMatches++;
  154.     }
  155.  
  156.     return nMatches;
  157. }
  158.  
  159. /**
  160.  * Converts the input string to lower-case.
  161.  */
  162. static inline std::wstring& WStrLower(std::wstring& wstrInput)
  163. {
  164.     std::transform(wstrInput.begin(), wstrInput.end(), wstrInput.begin(), ::tolower);
  165.     return wstrInput;
  166. }
  167.  
  168. /**
  169.  * Converts the input string to upper-case.
  170.  */
  171. static inline std::wstring& WStrUpper(std::wstring& wstrInput)
  172. {
  173.     std::transform(wstrInput.begin(), wstrInput.end(), wstrInput.begin(), ::toupper);
  174.     return wstrInput;
  175. }
  176.  
  177.  
  178. /**
  179.  * Trim
  180.  *
  181.  * Removes whitespace from the strings beginning/end.
  182.  */
  183. static inline std::wstring& trim(std::wstring& input)
  184. {
  185.     input.erase(0, input.find_first_not_of(L' '));
  186.     input.erase(input.find_last_not_of(L' ') + 1);
  187.     return input;
  188. }
  189.  
  190. /**
  191.  * RemoveSpecialChars
  192.  *
  193.  * Removes special characters from the input string.
  194.  */
  195. static inline std::wstring& RemoveSpecialChars(std::wstring& input)
  196. {
  197.     std::wstring wstrNewString;
  198.     static const wchar_t wszInvalidChars[] = { L'*', L'&' };
  199.  
  200.     for (unsigned int x = 0; x < input.size(); x++)
  201.     {
  202.         if (input.at(x) != wszInvalidChars[0] &&
  203.             input.at(x) != wszInvalidChars[1])
  204.             wstrNewString += input.at(x);
  205.     }
  206.  
  207.     input = wstrNewString;
  208.     return input;
  209. }
  210.  
  211. /**
  212.  * BuildFunctionCall
  213.  *
  214.  * Builds a function based on the input information given.
  215.  */
  216. static inline std::wstring BuildFunctionCall(functionentry_t& f)
  217. {
  218.     //
  219.     // Invalid Argument Variables
  220.     //
  221.     static const std::wstring wstrInvalidArgument = L"INVALID_ARG";
  222.     int nInvalidCount = 0;
  223.  
  224.     //
  225.     // Parse for function arguments..
  226.     //
  227.     std::list< std::wstring > listArguments;
  228.     std::wstring::size_type start = 0;
  229.     std::wstring::size_type end = f.RawArguments.find(L",");
  230.     while (end != std::wstring::npos)
  231.     {
  232.         listArguments.push_back(trim(f.RawArguments.substr(start, end - start)));
  233.         start = end + 1;
  234.         end = f.RawArguments.find(L",", start);
  235.     }
  236.     listArguments.push_back(trim(f.RawArguments.substr(start)));
  237.  
  238.     //
  239.     // Parse for argument variables...
  240.     //
  241.     std::list< std::wstring > listFuncArgs;
  242.     for (std::list< std::wstring >::iterator iter = listArguments.begin(), iterend = listArguments.end(); iter != iterend; ++iter)
  243.     {
  244.         // Cleanup argument whitespace..
  245.         const std::wstring wstrRawArgument = *iter;
  246.         std::wstring wstrArgument = trim(std::wstring(*iter));
  247.  
  248.         // Determine space count..
  249.         std::wstring::size_type numSpaces = std::count_if(wstrArgument.begin(), wstrArgument.end(),
  250.             [](const wchar_t wch) { return (wch == L' '); }
  251.         );
  252.  
  253.         // Determine how many keywords we have (ex. const, class, struct)
  254.         std::wstring::size_type numKeywords = 0;
  255.         numKeywords += (WStrLower(wstrArgument).find(L"class ") == -1) ? 0 : 1;
  256.         numKeywords += (WStrLower(wstrArgument).find(L"const ") == -1) ? 0 : 1;
  257.         numKeywords += (WStrLower(wstrArgument).find(L"struct ") == -1) ? 0 : 1;
  258.  
  259.         // Are we a normal argument with no keywords?
  260.         if (numSpaces == 1 && numKeywords == 0)
  261.         {
  262.             std::wstring wstrArg = wstrRawArgument.substr(wstrRawArgument.find_last_of(L" ") + 1);
  263.             listFuncArgs.push_back(RemoveSpecialChars(wstrArg));
  264.         }
  265.  
  266.         // Are we an argument with keywords?
  267.         else if (numSpaces >= 2 && numKeywords > 0)
  268.         {
  269.             std::wstring wstrArg = wstrRawArgument.substr(wstrRawArgument.find_last_of(L" ") + 1);
  270.             listFuncArgs.push_back(RemoveSpecialChars(wstrArg));
  271.         }
  272.  
  273.         // Is there a space between an astrisk?
  274.         else if (numSpaces == 2 && numKeywords == 0)
  275.         {
  276.             std::wstring wstrArg = wstrRawArgument.substr(wstrRawArgument.find_last_of(L" ") + 1);
  277.             listFuncArgs.push_back(RemoveSpecialChars(wstrArg));
  278.         }
  279.  
  280.         else if ((numSpaces == 1 || numSpaces == 2) && numKeywords > 0)
  281.         {
  282.             ++nInvalidCount;
  283.  
  284.             // Create a temp argument for this invalid arg.
  285.             std::wstringstream wstrStreamFuncArg(wstrInvalidArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
  286.             wstrStreamFuncArg << (nInvalidCount - 1);
  287.             listFuncArgs.push_back(wstrStreamFuncArg.str());
  288.  
  289.             // Fix the original functions argument list..
  290.             std::wstringstream wstrStreamArg(wstrRawArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
  291.             wstrStreamArg << L" " << wstrInvalidArgument << (nInvalidCount - 1);
  292.             *iter = wstrStreamArg.str();
  293.         }
  294.  
  295.         // Are we just the word void?
  296.         else if (numSpaces == 0 && numKeywords == 0 && wstrArgument.length() == 4 && wstrArgument == L"void")
  297.         {
  298.             // Don't push anything or we will create invalid calls..
  299.         }
  300.  
  301.         // Are we just a single word..
  302.         else if (numSpaces == 0 && numKeywords == 0 && wstrArgument.length() > 0)
  303.         {
  304.             ++nInvalidCount;
  305.  
  306.             // Create a temp argument for this invalid arg.
  307.             std::wstringstream wstrStreamFuncArg(wstrInvalidArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
  308.             wstrStreamFuncArg << (nInvalidCount - 1);
  309.             listFuncArgs.push_back(wstrStreamFuncArg.str());
  310.  
  311.             // Fix the original functions argument list..
  312.             std::wstringstream wstrStreamArg(wstrRawArgument, std::ios_base::in | std::ios_base::out | std::ios_base::ate);
  313.             wstrStreamArg << L" " << wstrInvalidArgument << (nInvalidCount - 1);
  314.             *iter = wstrStreamArg.str();
  315.         }
  316.  
  317.         // Completely invalid argument not recognized yet..
  318.         else
  319.         {
  320.             std::wcout << L"=================================================" << std::endl;
  321.             std::wcout << L"Could not find a valid argument while parsing: " << f.Function << L", debug info:" << std::endl;
  322.             std::wcout << L"=================================================" << std::endl;
  323.             std::wcout << f.RawFunction << std::endl;
  324.             std::wcout << L"    Argument: " << wstrRawArgument << std::endl;
  325.             std::wcout << L"    Space count: " << numSpaces << std::endl << L"    Keyword count: " << numKeywords << std::endl;
  326.             std::wcout << L"    Arguments: " << f.RawArguments << std::endl;
  327.         }
  328.     }
  329.  
  330.     //
  331.     // Build the full function with parsed data..
  332.     //
  333.     std::wstringstream wstrFullFunction;
  334.     wstrFullFunction << f.Return << L" __stdcall new{INTERFACE}::" << f.Function << L"( ";
  335.  
  336.     int nCommaCount = listArguments.size() - 1;
  337.     std::for_each(listArguments.begin(), listArguments.end(),
  338.         [&](const std::wstring& wstr)
  339.     {
  340.         wstrFullFunction << wstr;
  341.         f.FixedArguments += wstr;
  342.         if (nCommaCount)
  343.         {
  344.             wstrFullFunction << L", ";
  345.             f.FixedArguments += L", ";
  346.         }
  347.         --nCommaCount;
  348.     });
  349.     wstrFullFunction << L" )" << std::endl << L"{" << std::endl;
  350.  
  351.     if (f.Return == L"void")
  352.         wstrFullFunction << L"    m_vOrigInterface->" << f.Function << L"(";
  353.     else
  354.         wstrFullFunction << L"    return m_vOrigInterface->" << f.Function << L"( ";
  355.  
  356.     nCommaCount = listFuncArgs.size() - 1;
  357.     std::for_each(listFuncArgs.begin(), listFuncArgs.end(),
  358.         [&](const std::wstring& wstr)
  359.     {
  360.         wstrFullFunction << wstr;
  361.         if (nCommaCount)
  362.             wstrFullFunction << L", ";
  363.         --nCommaCount;
  364.     });
  365.     wstrFullFunction << L" );" << std::endl << L"}" << std::endl;
  366.  
  367.     return wstrFullFunction.str();
  368. }
  369.  
  370. #endif // __DEFINES_H_INCLUDED__
main.cpp
  1. /**
  2.  * dxgen - (c) 2011-2013 atom0s [atom0s@live.com]
  3.  *
  4.  * Slim wrapper generator for Direct3D9. Parses d3d9.h for
  5.  * interfaces and generates wrappers for each interface
  6.  * found.
  7.  *
  8.  */
  9.  
  10. #include <Windows.h>
  11. #include "defines.h"
  12.  
  13. #include <cmath>
  14. #include <functional>
  15. #include <list>
  16. #include <map>
  17.  
  18. int __cdecl main(int argc, wchar_t* argv[])
  19. {
  20.     // Ensure a target header was given..
  21.     if (argc != 2 || strlen((char*)argv[1]) == 0)
  22.     {
  23.         std::wcout << L"ERROR: No input file was given!" << std::endl;
  24.         std::wcout << L"Usage: dxgen.exe [input_file]" << std::endl;
  25.         return 0;
  26.     }
  27.  
  28.     // Attempt to load target header file..
  29.     std::wifstream wifs((char*)argv[1]);
  30.     if (!wifs.is_open())
  31.     {
  32.         std::wcout << L"ERROR: Failed to open target file, " << (char*)argv[1] << std::endl;
  33.         return 0;
  34.     }
  35.  
  36.     // Read and close file..
  37.     std::wstring wstrFileData((std::istreambuf_iterator< wchar_t >(wifs)), std::istreambuf_iterator< wchar_t >());
  38.     wifs.close();
  39.  
  40.     // Scan and dump all interfaces..
  41.     std::wcout << std::endl;
  42.     std::wcout << L"=====================================================" << std::endl;
  43.     std::wcout << L"Parsing header file for interfaces..." << std::endl;
  44.     std::wcout << L"=====================================================" << std::endl;
  45.  
  46.     std::map< std::wstring, std::wstring > mapInterfaces;
  47.     for (std::wsregex_iterator iter_interfaces(wstrFileData.begin(), wstrFileData.end(), g_vRegexInterface); iter_interfaces != g_vRegexIteratorEnd; ++iter_interfaces)
  48.     {
  49.         // Copy full interface from file contents..
  50.         int nStartPos = iter_interfaces->position();
  51.         int nBracePos = (wstrFileData.find(L"}", nStartPos)) + 2;
  52.         std::wstring wstrInterface(wstrFileData.substr(nStartPos, (nBracePos - nStartPos)));
  53.  
  54.         // Store this interface..
  55.         mapInterfaces[(*iter_interfaces)[1]] = wstrInterface;
  56.         std::wcout << L"Found interface: " << (*iter_interfaces)[1] << std::endl;
  57.     }
  58.  
  59.     // Assure we found some interfaces..
  60.     if (mapInterfaces.size() == 0)
  61.     {
  62.         std::wcout << L"ERROR: Failed to parse for any interfaces." << std::endl;
  63.         return 0;
  64.     }
  65.  
  66.     // Parse each interface for functions..
  67.     std::wcout << std::endl;
  68.     std::wcout << L"=====================================================" << std::endl;
  69.     std::wcout << L"Parsing interfaces for functions..." << std::endl;
  70.     std::wcout << L"=====================================================" << std::endl;
  71.  
  72.     std::map< std::pair< std::wstring, std::wstring >, std::list< functionentry_t > > mapFunctions;
  73.     std::for_each(mapInterfaces.begin(), mapInterfaces.end(),
  74.         [&](const std::pair< std::wstring, std::wstring >& p)
  75.     {
  76.         std::wcout << L"Parsing interface: " << p.first << std::endl;
  77.         std::list< functionentry_t > listFunctions;
  78.  
  79.         for (std::wsregex_iterator iter_functions(p.second.begin(), p.second.end(), g_vRegexFunctions); iter_functions != g_vRegexIteratorEnd; ++iter_functions)
  80.         {
  81.             int nGroups = std::count_if(iter_functions->begin(), iter_functions->end(), [](const std::wssub_match& smatch) { return (smatch.matched == true); });
  82.  
  83.             // Create function entry..
  84.             functionentry_t functionEntry;
  85.             functionEntry.RawFunction = (*iter_functions)[0].str();
  86.             functionEntry.Return = (nGroups == 3) ? L"HRESULT" : (*iter_functions)[3].str();
  87.             functionEntry.Function = (nGroups == 3) ? (*iter_functions)[1].str() : (*iter_functions)[4].str();
  88.             functionEntry.RawArguments = (nGroups == 3) ? (*iter_functions)[2].str() : (*iter_functions)[5].str();
  89.  
  90.             // Cleanup unneeded macros..
  91.             WStrRep(functionEntry.RawArguments, L"THIS_", L"");
  92.             WStrRep(functionEntry.RawArguments, L"THIS", L"void");
  93.  
  94.             // Cleanup double-spaces..
  95.             WStrRep(functionEntry.RawArguments, L"  ", L" ");
  96.  
  97.             // Store this function entry..
  98.             listFunctions.push_back(functionEntry);
  99.             std::wcout << L"    Found function: " << functionEntry.Function << std::endl;
  100.         }
  101.  
  102.         // Store functions.
  103.         mapFunctions[p] = listFunctions;
  104.     });
  105.  
  106.     // Ensure all maps have functions..
  107.     std::wcout << std::endl;
  108.     std::wcout << L"=====================================================" << std::endl;
  109.     std::wcout << L"Validating interface function lists..." << std::endl;
  110.     std::wcout << L"=====================================================" << std::endl;
  111.  
  112.     std::map< std::pair< std::wstring, std::wstring >, std::list< functionentry_t > >::iterator iter_func = mapFunctions.begin();
  113.     while (iter_func != mapFunctions.end())
  114.     {
  115.         std::wcout << L"Validating interface: " << (*iter_func).first.first << " ... ";
  116.  
  117.         if ((*iter_func).second.size() == 0)
  118.         {
  119.             std::wcout << L"Invalid! Removing.." << std::endl;
  120.             mapFunctions.erase(iter_func++);
  121.         }
  122.         else
  123.         {
  124.             std::wcout << L"Ok!" << std::endl;
  125.             ++iter_func;
  126.         }
  127.     }
  128.  
  129.     // Prepare path information..
  130.     wchar_t wszCurrentDirectory[MAX_PATH] = { 0 };
  131.     GetCurrentDirectory(MAX_PATH, wszCurrentDirectory);
  132.     std::wstring wstrOutputPath = std::wstring(wszCurrentDirectory) + L"\\includes\\";
  133.  
  134.     if (GetFileAttributes(wstrOutputPath.c_str()) == 0xFFFFFFFF)
  135.         CreateDirectory(wstrOutputPath.c_str(), NULL);
  136.  
  137.     // Create source files for each found interface..
  138.     std::wcout << std::endl;
  139.     std::wcout << L"=====================================================" << std::endl;
  140.     std::wcout << L"Creating source files for found interfaces..." << std::endl;
  141.     std::wcout << L"=====================================================" << std::endl;
  142.  
  143.     for (auto iter = mapFunctions.begin(), iterend = mapFunctions.end(); iter != iterend; ++iter)
  144.     {
  145.         std::wcout << L"Creating source file: " << (*iter).first.first << L".cpp" << std::endl;
  146.  
  147.         // Iterate and create each function body..
  148.         std::list< std::wstring > listFuncBodies;
  149.         for (auto fiter = (*iter).second.begin(), fiterend = (*iter).second.end(); fiter != fiterend; ++fiter)
  150.         {
  151.             std::wcout << L"    Building function: " << (*fiter).Function << std::endl;
  152.             std::wstring wstrFunctionBody = BuildFunctionCall(*fiter);
  153.             WStrRep(wstrFunctionBody, L"{INTERFACE}", (*iter).first.first);
  154.             listFuncBodies.push_back(wstrFunctionBody);
  155.         }
  156.  
  157.         // Create our output file..
  158.         std::wofstream wofs(std::wstring(wstrOutputPath + L"new" + (*iter).first.first + L".cpp"), std::ios_base::binary);
  159.         if (!wofs.is_open())
  160.         {
  161.             std::wcout << L"Failed to create file: " << (*iter).first.first << L".cpp" << std::endl;
  162.         }
  163.         else
  164.         {
  165.             std::wstring wstrSourceFile;
  166.             std::for_each(g_vSourceTemplate, g_vSourceTemplate + (sizeof(g_vSourceTemplate) / sizeof(g_vSourceTemplate[0])),
  167.                 [&](const std::wstring& wstr)
  168.             {
  169.                 std::wstring wstrLine = wstr;
  170.                 std::wstring wstrLower = (*iter).first.first;
  171.                 std::wstring wstrUpper = (*iter).first.first;
  172.  
  173.                 std::transform(wstrLower.begin(), wstrLower.end(), wstrLower.begin(), ::tolower);
  174.                 std::transform(wstrUpper.begin(), wstrUpper.end(), wstrUpper.begin(), ::toupper);
  175.  
  176.                 WStrRep(wstrLine, L"{INTERFACE}", (*iter).first.first);
  177.                 WStrRep(wstrLine, L"{INTERFACELOWER}", wstrLower);
  178.                 WStrRep(wstrLine, L"{INTERFACEUPPER}", wstrUpper);
  179.  
  180.                 wstrSourceFile += wstrLine + L"\r\n";
  181.             });
  182.  
  183.             wofs << wstrSourceFile;
  184.  
  185.             std::ostream_iterator< std::wstring, wchar_t > ositer(wofs, L"\r\n");
  186.             std::copy(listFuncBodies.begin(), listFuncBodies.end(),
  187.                 std::ostream_iterator< std::wstring, wchar_t >(wofs, L"\r\n")
  188.                 );
  189.  
  190.             wofs.close();
  191.         }
  192.     }
  193.  
  194.     // Create header files for each found interface..
  195.     std::wcout << std::endl;
  196.     std::wcout << L"=====================================================" << std::endl;
  197.     std::wcout << L"Creating header files for found interfaces..." << std::endl;
  198.     std::wcout << L"=====================================================" << std::endl;
  199.  
  200.     std::for_each(mapFunctions.begin(), mapFunctions.end(),
  201.         [&](const std::pair< std::pair< std::wstring, std::wstring >, std::list< functionentry_t > >& p)
  202.     {
  203.         std::wcout << L"Creating header file: " << p.first.first << L".h ... ";
  204.  
  205.         std::wofstream wofs(std::wstring(wstrOutputPath + L"new" + p.first.first + L".h"), std::ios_base::binary);
  206.         if (!wofs.is_open())
  207.         {
  208.             std::wcout << L"Failed!" << std::endl;
  209.         }
  210.         else
  211.         {
  212.             // Generate header file..
  213.             std::wstring wstrHeader;
  214.             std::for_each(g_vHeaderTemplate, g_vHeaderTemplate + (sizeof(g_vHeaderTemplate) / sizeof(g_vHeaderTemplate[0])),
  215.                 [&](const std::wstring& wstr)
  216.             {
  217.                 std::wstring wstrLine = wstr;
  218.                 std::wstring wstrLower = p.first.first;
  219.                 std::wstring wstrUpper = p.first.first;
  220.  
  221.                 std::transform(wstrLower.begin(), wstrLower.end(), wstrLower.begin(), ::tolower);
  222.                 std::transform(wstrUpper.begin(), wstrUpper.end(), wstrUpper.begin(), ::toupper);
  223.  
  224.                 WStrRep(wstrLine, L"{INTERFACE}", p.first.first);
  225.                 WStrRep(wstrLine, L"{INTERFACELOWER}", wstrLower);
  226.                 WStrRep(wstrLine, L"{INTERFACEUPPER}", wstrUpper);
  227.  
  228.                 wstrHeader += wstrLine + L"\r\n";
  229.             });
  230.  
  231.             // Generate class data..
  232.             std::wstring wstrClassData;
  233.             std::for_each(p.second.begin(), p.second.end(),
  234.                 [&](const functionentry_t& f)
  235.             {
  236.                 std::wstring wstrReturn = f.Return;
  237.                 std::wstring wstrFunction = f.Function;
  238.                 std::wstring wstrArguments = f.FixedArguments;
  239.  
  240.                 WStrRep(wstrArguments, L"THIS_", L"");
  241.                 WStrRep(wstrArguments, L"THIS", L"");
  242.                 trim(wstrArguments);
  243.  
  244.                 if (wstrArguments.size() == 0)
  245.                     wstrArguments = L"void";
  246.  
  247.                 wstrArguments.insert(wstrArguments.cbegin(), L' ');
  248.                 wstrArguments.insert(wstrArguments.cend(), L' ');
  249.  
  250.                 std::wstring wstrFullFunction = g_vFunctionTemplate;
  251.                 WStrRep(wstrFullFunction, L"{RETURN}", wstrReturn);
  252.                 WStrRep(wstrFullFunction, L"{FUNCTION}", wstrFunction);
  253.                 WStrRep(wstrFullFunction, L"{ARGUMENTS}", wstrArguments);
  254.  
  255.                 wstrClassData += L"    " + wstrFullFunction + L"\r\n";
  256.             });
  257.  
  258.             WStrRep(wstrHeader, L"{CLASS_DATA}", wstrClassData);
  259.  
  260.             wofs << wstrHeader;
  261.             wofs.close();
  262.  
  263.             std::wcout << L"Ok!" << std::endl;
  264.         }
  265.     });
  266.  
  267.     std::cin.sync();
  268.     std::cin.ignore();
  269.  
  270.     return 0;
  271. }
An example of the output generated:
http://pastebin.com/jMKaQ7FK
http://pastebin.com/BxgnveUB
Derp~
Need a great web host? Check out: AnHonestHost.com


Donations can be made via Paypal:
https://www.paypal.me/atom0s
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest