(tools) add the tool used to generate the d3d headers.

This commit is contained in:
aliaspider 2018-01-21 04:28:06 +01:00
parent 6b9dc2205b
commit c8027ebe1d
5 changed files with 995 additions and 8 deletions

View File

@ -1,4 +1,4 @@
//
//
// peglib.h
//
// Copyright (c) 2015-17 Yuji Hirose. All rights reserved.
@ -2238,6 +2238,20 @@ struct AstBase : public Annotation
std::vector<std::shared_ptr<AstBase<Annotation>>> nodes;
std::shared_ptr<AstBase<Annotation>> parent;
static peg::AstBase<Annotation> empty;
AstBase<Annotation>& operator [] (const char* name)
{
for(std::shared_ptr<AstBase<Annotation>>& node : nodes)
{
if(node->name == name)
return *node;
}
return empty;
}
operator const char *()
{
return token.c_str();
}
};
template <typename T>
@ -2770,6 +2784,14 @@ private:
} // namespace peg
template<class _Elem, class _Traits, typename Annotation>
std::basic_ios<_Elem, _Traits> &operator << (std::basic_ios<_Elem, _Traits> &ios,
peg::AstBase<Annotation> &node)
{
return ios << node.token.c_str();
}
#endif
// vim: et ts=4 sw=4 cin cino={1s ff=unix

160
tools/com-parser/Makefile Normal file
View File

@ -0,0 +1,160 @@
TARGET = com-parse
DEBUG = 0
GENDEPS = 1
TARGET_ARCH = amd64
OS ?= win32
OBJ :=
OBJ += com-parse.o
EXE_EXT := $(suffix $(wildcard $(MAKE).*))
ifeq ($(compiler),)
ifeq ($(patsubst %.exe,%,$(basename $(CC))),cl)
compiler = msvc
else
compiler = gcc
endif
endif
CC_OUT = -o $(NOTHING)
CXX_OUT = $(CC_OUT)
LD_OUT = $(CC_OUT)
OBJ_EXT := o
ifeq ($(DEBUG),1)
DEFINES += -DDEBUG -D_DEBUG
endif
ifeq ($(compiler),msvc)
ARCH = amd64
ARCH2 = x64
TARGET_ARCH2 = x64
CROSS = amd64
WindowsSdkDir = C:\Program Files (x86)\Windows Kits\10\$(NOTHING)
WindowsSDKVersion := 10.0.14393.0\$(NOTHING)
VCINSTALLDIR := C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\$(NOTHING)
INCLUDE := $(VCINSTALLDIR)include;$(VCINSTALLDIR)atlmfc\include;$(WindowsSdkDir)include\$(WindowsSDKVersion)ucrt;$(WindowsSdkDir)include\$(WindowsSDKVersion)shared;$(WindowsSdkDir)include\$(WindowsSDKVersion)um;
LIB := $(VCINSTALLDIR)LIB\$(CROSS);$(VCINSTALLDIR)atlmfc\lib\$(CROSS);$(WindowsSdkDir)lib\$(WindowsSDKVersion)ucrt\$(TARGET_ARCH2);$(WindowsSdkDir)lib\$(WindowsSDKVersion)um\$(TARGET_ARCH2);C:\Program Files (x86)\NVIDIA Corporation\Cg\lib.$(TARGET_ARCH2);C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Lib\$(TARGET_ARCH2);
LIBPATH := $(VCINSTALLDIR)LIB\$(CROSS);$(VCINSTALLDIR)atlmfc\lib\$(CROSS);
PATH := $(shell IFS=$$'\n'; cygpath "$(VCINSTALLDIR)bin\\$(CROSS)"):$(shell IFS=$$'\n'; cygpath "$(WindowsSdkDir)\bin\\$(ARCH2)"):$(PATH)
export INCLUDE := $(INCLUDE)
export LIB := $(LIB)
export LIBPATH := $(LIBPATH)
export PATH := $(PATH)
DEFINES :=
FLAGS += -nologo
FLAGS += -Gm- -Zc:inline -fp:precise -Zc:forScope -Gd -Oi -volatile:iso
#FLAGS += -GR-
CFLAGS += -TC
CXXFLAGS += -TP -EHsc
WARNINGS += -WX -W3
WARNINGS += -wd4101 -wd4996 -wd4244 -wd4267 -wd4090 -wd4305 -wd4146 -wd4334 -wd4018
CC = cl.exe
CXX = cl.exe
LD = link.exe
RC = rc.exe
LIBS += shell32.lib user32.lib gdi32.lib comdlg32.lib winmm.lib ole32.lib
LDFLAGS += -nologo -wx -nxcompat -machine:$(TARGET_ARCH2)
ifeq ($(DEBUG),1)
FLAGS += -GS -Gy -Od -RTC1 -D_SECURE_SCL=1 -Zi
FLAGS += -MDd
LDFLAGS += -DEBUG
DEFINES += -DDEBUG -D_DEBUG
else
FLAGS += -GS- -Gy- -O2 -Ob2 -GF -GT -Oy -Ot -D_SECURE_SCL=0
FLAGS += -MD
endif
OBJ := $(OBJ:.o=.obj)
LDFLAGS += -WX -SUBSYSTEM:WINDOWS -ENTRY:mainCRTStartup
DEFINES := $(patsubst -f%,,$(DEFINES))
LDFLAGS := $(patsubst -l%,%.lib,$(LDFLAGS))
LIBS := $(filter-out -lm,$(LIBS))
LIBS := $(patsubst -l%,%.lib,$(LIBS))
DEPFLAGS = -showIncludes | tee $*.dtemp | sed /'Note: including file:'/d
MAKEDEPS = echo $@: $< \\ > $*.depend && \
grep 'Note: including file:' $*.dtemp \
| sed '/$(subst \,\\,$(WindowsSdkDir))/Id; /$(subst \,\\,$(VCINSTALLDIR))/Id; s/Note: including file:[ ]*//g; s/\\/\//g; s/ /\\ /g; s/.*/ & \\/g' \
>> $*.depend && \
rm -f $*.dtemp
OBJ_EXT := obj
CC_OUT := -Fo:
CXX_OUT := $(CC_OUT)
LD_OUT := -out:
else
RC := windres
DEPFLAGS = -MT $@ -MMD -MP -MF $(BUILD_DIR)$*.depend
LD = $(CXX)
ifeq ($(DEBUG),1)
FLAGS += -g -O0
else
FLAGS += -O3
endif
endif
INCLUDE_DIRS += -I. -I../../deps/peglib
$(info os : $(OS))
$(info host : $(ARCH))
$(info target : $(TARGET_ARCH))
$(info compiler : $(compiler))
all: $(TARGET)$(EXE_EXT)
%.h:
touch $*.tmp
$(CXX) $*.tmp -DCINTERFACE -D_REFIID_DEFINED= -D_REFGUID_DEFINED= -D_HRESULT_DEFINED= \
-EP -FI $@ $(FLAGS) $(CXXFLAGS) $(DEFINES) $(INCLUDE_DIRS) $(WARNINGS) > $@
rm $*.tmp
SHELL:=$(SHELL) -o pipefail
ifeq ($(GENDEPS),0)
DEPFLAGS :=
MAKEDEPS :=
endif
%.$(OBJ_EXT): %.cpp
$(CXX) -c $(CXX_OUT)$@ $< $(FLAGS) $(CXXFLAGS) $(DEFINES) $(INCLUDE_DIRS) $(WARNINGS) $(DEPFLAGS)
@$(MAKEDEPS)
%.$(OBJ_EXT): %.c
$(CC) -c $(CC_OUT)$@ $< $(FLAGS) $(CFLAGS) $(DEFINES) $(INCLUDE_DIRS) $(WARNINGS) $(DEPFLAGS)
@$(MAKEDEPS)
%.res: %.rc
$(RC) $<
mv $*.res $@
$(TARGET)$(EXE_EXT): $(OBJ) .$(TARGET).last
@touch .$(TARGET).last
$(LD) $(OBJ) $(LDFLAGS) $(LIBS) $(LD_OUT)$@
%.depend: ;
%.last: ;
.FORCE:
clean:
rm -f $(OBJ) $(TARGET)$(EXE_EXT)
rm -f $(TARGET)
rm -f .$(TARGET).last
rm -f $(OBJ:.obj=.depend)
.PHONY: clean all
.PRECIOUS: %.depend %.last
-include $(patsubst %.obj,%.depend,$(filter %.obj,$(OBJ)))

View File

@ -0,0 +1,775 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2018 - Ali Bouhlel
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <iostream>
#include <peglib.h>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace peg;
using namespace std;
template <typename Annotation>
AstBase<Annotation> AstBase<Annotation>::empty = AstBase<Annotation>("", 0, 0, "", string(""));
//bool use_typedefs = false;
bool use_typedefs = true;
//const char* prefix_seperator = "_";
const char* prefix_seperator = "";
vector<string> ignored_fn_prefixes_list =
{
"OM",
"IA",
"RS",
};
vector<string> fn_prefixes_list =
{
"OM",
"IA",
"RS",
"VS",
"PS",
"GS",
"DS",
"CS",
};
bool move_fn_prefix_after_action = true;
vector<string> ignored_types_list =
{
"AsyncIUnknown",
"IMarshal",
"IMalloc",
"IEnumString",
"ISequentialStream",
"IStream",
"IRpcChannelBuffer",
"IAsyncRpcChannelBuffer",
"IRpcProxyBuffer",
"IServerSecurity",
"IRpcOptions",
"IGlobalOptions",
"ISurrogate",
"ISynchronize",
"ISynchronizeEvent",
"IDataObject",
"IDataAdviseHolder",
"IDirectWriterLock",
"IDummyHICONIncluder",
"IDispatch",
"IDropSource",
"IDropTarget",
"IDataFilter",
"IDropSourceNotify",
};
const char* required_prefix = "ID";
vector<string> ignored_functions_list =
{
"Release",
"QueryInterface",
"AddRef",
"GetParent",
"GetAdapter",
"GetDevice",
"GetDesc",
"GetType",
"SetName",
"SetPrivateDataInterface",
"SetPrivateData",
"GetPrivateData",
"OpenSharedHandle",
"CreateSharedHandle",
"OpenSharedHandleByName",
"SetTrackingOptions",
};
vector<string> overloaded_list =
{
"Release",
"QueryInterface",
"AddRef",
"GetParent",
"GetAdapter",
"GetDesc",
"GetType",
"SetName",
"SetPrivateDataInterface",
"SetPrivateData",
"GetPrivateData",
"Reset",
"Signal",
"BeginEvent",
"EndEvent",
"SetMarker",
"AssertResourceState",
"GetFeatureMask",
"SetFeatureMask",
"GetFrameStatistics",
"Close",
"SetEvictionPriority",
"GetEvictionPriority",
"GetResource",
"GetDataSize",
"GetContextFlags",
"GetCertificate",
"GetCertificateSize",
};
vector<string> action_list =
{
"Release",
"Get",
"Set",
"Enum",
"Get",
"Query",
"Add",
"Signal",
"Begin",
"End",
"Assert",
"Close",
"Map",
"Unmap"
};
vector<string> derived_types_list =
{
"ID3D12Device",
"ID3D12Debug",
"ID3D12DebugDevice",
"ID3D12DebugCommandList",
"IDXGIFactory1",
"IDXGIAdapter1",
"IDXGISurface1",
"IDXGISwapChain3",
"IDXGIOutput",
"IDXGIDevice",
};
vector<string> base_objects_list =
{
"IUnknown",
"ID3D12Object",
"ID3D12Resource",
"IDXGIObject",
"IDXGIResource",
"D3D11Resource",
};
//string insert_name(const char* fname, const char* name)
string insert_name(const string& fname, const string& name)
{
string str;
for(string action: action_list)
{
if(!strncmp(fname.c_str(), action.c_str(), action.length()))
{
if(name.length() == 2 && name[1] == 'S')
{
if(!strncmp(fname.c_str() + action.length(), "Shader", strlen("Shader")))
return action + name[0] + (fname.c_str() + action.length());
else
return action + name[0] + "Shader" + (fname.c_str() + action.length());
}
else
return action + name + (fname.c_str() + action.length());
}
}
return string(fname) + name;
}
//string insert_name(string fname, string name)
//{
// return insert_name(fname.c_str(), name.c_str());
//}
string get_derived_basename(const char *name)
{
string str = name;
if(::isdigit(str.back()))
str.pop_back();
return str;
}
string get_derived_basename(string name)
{
return get_derived_basename(name.c_str());
}
string get_prefix(const char *type)
{
string prefix;
if(*type != 'I')
return type;
type++;
while (::isalnum(*type) && !::islower(*type))
prefix.push_back(*type++);
prefix.pop_back();
return prefix;
}
string get_prefix(const string &type)
{
return get_prefix(type.c_str());
}
string clean_name(const char *name)
{
string str;
if (name[0] == 'p' && name[1] == 'p' && name[2] == 'v' && ::isupper(name[3]))
name += 3;
if (name[0] == 'p' && name[1] == 'p' && ::isupper(name[2]))
name += 2;
else if ((*name == 'p' || *name == 'b') && ::isupper(name[1]))
name ++;
bool was_upper = false;
if (*name)
{
if (::isupper(*name))
{
was_upper = true;
str = (char)::tolower(*name);
}
else
str = *name;
}
while (*++name)
{
if (::isupper(*name))
{
if(!was_upper && !::isdigit(str.back()))
str = str + '_';
was_upper = true;
str += (char)::tolower(*name);
}
else
{
was_upper = false;
str += *name;
}
}
if(str == "enum")
str = "enumerator";
return str;
}
struct name_pair{
string name;
string original;
};
class ComFunction
{
public:
struct param_t
{
name_pair type;
name_pair ptr;
name_pair name;
int array_size = 0;
bool const_ = false;
bool base = false;
bool derived = false;
};
param_t this_;
vector<param_t> params;
string riid;
string name;
string original_name;
string return_type;
string prefix;
bool overloaded = false;
bool ignored = false;
bool preferred = false;
ComFunction(Ast node)
{
original_name = node["FunctionName"];
return_type = node["ReturnType"];
for (auto param_ : node["Parameters"].nodes)
{
Ast &param = *param_;
param_t p;
p.type.original = param["Type"]["Name"];
p.const_ = param["Type"]["TypeQualifier"] == "const";
if(p.type.original == "REFIID")
{
riid = string("I") + prefix;
continue;
}
if(!riid.empty())
{
if(param["Name"][2] == 'v')
riid += param["Name"] + 3;
else
riid += param["Name"] + 2;
break;
}
p.ptr.original = param["Type"]["Pointer"];
p.ptr.name = p.ptr.original;
if(use_typedefs &&
(prefix.empty() || (p.type.original[0] == 'I' && !strncmp(p.type.original.c_str() + 1, prefix.c_str(), prefix.length())))
)
{
p.type.name = p.type.original.c_str() + 1;
if(::isdigit(p.type.name.back()))
p.type.name.pop_back();
if(!p.ptr.name.empty())
p.ptr.name.pop_back();
}
else
{
p.type.name = p.type.original;
p.ptr.name = p.ptr.name;
}
if (param.name == "This")
{
prefix = get_prefix(p.type.original);
p.name.original = param["Type"]["Name"] + 1 + prefix.length();
p.name.name = clean_name(p.name.original.c_str());
if(::isdigit(p.name.name.back()))
p.name.name.pop_back();
this_ = p;
}
else
{
p.name.original = param["Name"];
p.name.name = clean_name(p.name.original.c_str());
p.array_size = ::strtoul(param["ArraySize"], NULL, 10);
params.push_back(p);
}
}
if(original_name == "GetCPUDescriptorHandleForHeapStart")
{
param_t p;
p.type.name = p.type.original = return_type;
p.ptr.name = p.ptr.original = "*";
return_type = "void";
p.name.name = p.name.original = "out";
params.push_back(p);
}
for(string str : ignored_functions_list)
if(original_name == str)
ignored = true;
for(string str : ignored_types_list)
if(get_derived_basename(this_.type.original) == get_derived_basename(str))
ignored = true;
if(required_prefix)
if(strncmp(this_.type.original.c_str(), required_prefix, strlen(required_prefix)))
ignored = true;
for(string str : derived_types_list)
{
if(get_derived_basename(this_.type.original) == get_derived_basename(str))
{
this_.derived = true;
if(this_.type.original != str)
ignored = true;
}
for (param_t &param : params)
if(get_derived_basename(param.type.original) == get_derived_basename(str))
{
if(param.type.original != str)
param.derived = true;
else
{
// cout << param.type.original << endl;
preferred = true;
}
}
}
for(string str : overloaded_list)
if(original_name == str)
overloaded = true;
for(string str : base_objects_list)
{
if(this_.type.original == str)
this_.base = true;
for (param_t &param : params)
if(param.type.original == str)
param.base = true;
}
name = prefix + prefix_seperator;
if(overloaded && !this_.base)
{
name += insert_name(original_name, this_.name.original);
if(::isdigit(name.back()))
name.pop_back();
}
else
{
string fn_prefix;
for (string& str : ignored_fn_prefixes_list)
if(!strncmp(original_name.c_str(), str.c_str(), str.length()))
{
if(::isupper(original_name[str.length()]))
fn_prefix = str;
break;
}
if(!fn_prefix.empty())
{
name += original_name.c_str() + fn_prefix.length();
}
else
{
for (string str : fn_prefixes_list)
if(!strncmp(original_name.c_str(), str.c_str(), str.length()))
{
if(::isupper(original_name[str.length()]))
fn_prefix = str;
break;
}
if(!fn_prefix.empty())
name += insert_name(original_name.c_str() + fn_prefix.length(), fn_prefix.c_str());
else
name += original_name;
}
}
// if(original_name == "CreateCommandQueue" && ignored)
// cout << "ignored CreateCommandQueue !!" << __LINE__ << endl;
}
string str()
{
stringstream out;
out << "static inline " << return_type << " " << name << "(";
if(this_.base)
out << "void*";
else
out << this_.type.name << this_.ptr.name;
out << " " << this_.name.name;
for (param_t &param : params)
{
out << ", ";
if(param.const_)
out << "const ";
if(param.base)
out << "void*";
else
out << param.type.name << param.ptr.name;
out << " " << param.name.name;
if(param.array_size)
out << '[' << param.array_size << ']';
}
if(!riid.empty())
out << ", " << riid << "** out";
out << ")\n{\n";
out << " ";
if (return_type != "void")
out << "return ";
if(original_name == "GetCPUDescriptorHandleForHeapStart")
out << "((void (STDMETHODCALLTYPE *)(ID3D12DescriptorHeap*, D3D12_CPU_DESCRIPTOR_HANDLE*))\n ";
if(this_.base)
out << "((" << this_.type.original << this_.ptr.original << ')' << this_.name.name << ')';
else
out << this_.name.name;
out << "->lpVtbl->" << original_name;
if(original_name == "GetCPUDescriptorHandleForHeapStart")
out << ')';
out << '(' << this_.name.name;
for (param_t param : params)
{
out << ", ";
if(param.base || param.derived)
out << '(' << param.type.original << param.ptr.original << ')';
out << param.name.name;
}
if(!riid.empty())
out << ", __uuidof(" << riid << "), (void**)out";
out << ");\n";
out << "}\n";
return out.str();
}
};
class ComHeader
{
public:
shared_ptr<Ast> ast;
vector<ComFunction> functions;
vector<name_pair> types;
ComHeader(const char *filename)
{
string header;
{
ifstream fs(filename);
#if 0
stringstream ss;
ss << fs.rdbuf();
header = ss.str();
#else
while (!fs.eof())
{
char line[4096];
fs.getline(line, sizeof(line));
char* str = line;
while (*str && ::isspace(*str))
str++;
if (*str && !strncmp(str, "typedef struct ", strlen("typedef struct ")))
{
if(*str && strstr(str, "Vtbl"))
{
header += str;
header.push_back('\n');
while(*line)
{
fs.getline(line, sizeof(line));
str = line;
while (*str && ::isspace(*str))
str++;
if(*str)
{
header += str;
header.push_back('\n');
}
if(*str == '}')
break;
}
}
}
}
#endif
}
{
ofstream out("test.cpp.h");
out << header;
out.close();
}
string header_grammar;
{
ifstream fs("grammar.txt");
stringstream ss;
ss << fs.rdbuf();
header_grammar = ss.str();
}
parser parser;
parser.log = [&](size_t ln, size_t col, const string & msg)
{
cout << "Error parsing grammar:" << ln << ":" << col << ": " << msg << endl;
};
if (!parser.load_grammar(header_grammar.c_str()))
{
cout << "Failed to load grammar" << endl;
return;
}
parser.log = [&](size_t ln, size_t col, const string & msg)
{
cout << filename << ":" << ln << ":" << col << ": " << msg << endl;
};
parser.enable_ast();
if (!parser.parse_n(header.c_str(), header.size(), ast))
{
cout << "Error parsing header file: " << filename << endl;
return;
}
ast = AstOptimizer(false).optimize(ast);
if (ast->name != "Program")
{
cout << "Expected root node to be Program, not" << ast->name << endl;
return;
}
for (shared_ptr<Ast> node_ : ast->nodes)
{
Ast node = *node_;
if (node.name == "Function")
functions.push_back(node);
else if (node.name == "Line")
{
}
else if (node.name == "EndOfFile")
break;
else
{
// cout << "Unexcpected node " << node->name << endl;
}
}
for(ComFunction& fn : functions)
{
if(!fn.ignored && fn.preferred && ::isdigit(fn.name.back()))
{
fn.name.pop_back();
for(ComFunction& fn2 : functions)
if(&fn != &fn2 && !fn2.ignored && get_derived_basename(fn.original_name) == get_derived_basename(fn2.original_name))
{
// cout << &fn << &fn2 << fn.original_name << " " << fn2.original_name << endl;
// assert(fn2.preferred == false);
fn2.ignored = true;
// if(fn2.original_name == "CreateCommandQueue" && fn2.ignored)
// cout << "ignored CreateCommandQueue !!" << __LINE__ << endl;
}
}
}
for(ComFunction& fn : functions)
{
if(!fn.ignored)
{
bool known = false;
for(name_pair& known_type:types)
if (fn.this_.type.original == known_type.original)
{
known = true;
break;
}
if(!known)
types.push_back(fn.this_.type);
}
}
}
ComHeader(shared_ptr<Ast> ast_)
{
}
string str()
{
stringstream out;
int indent = 0;
for(name_pair known_type:types)
if (indent < known_type.original.length())
indent = known_type.original.length();
for(name_pair known_type:types)
{
out << "typedef " << known_type.original << '*' << string(indent + 1 - known_type.original.length(), ' ') << known_type.name << ";\n";
}
out << "\n\n";
for (ComFunction &fn : functions)
if(!fn.ignored)
out << fn.str();
return out.str();
}
};
template<class _Elem, class _Traits>
basic_ostream<_Elem, _Traits> &operator << (basic_ostream<_Elem, _Traits> &ios, ComHeader &header)
{
return ios << header.str();
}
int main(int argc, const char **argv)
{
const char *header_fn = argv[1];
ComHeader header(header_fn);
if (header.functions.empty())
return 1;
if (argc > 2)
cout << ast_to_s(header.ast) << flush;
ofstream out("test.h");
const char* basename = strrchr(argv[1], '/');
if(!basename)
basename = strrchr(argv[1], '\\');
if(basename)
basename++;
if(!basename)
basename = argv[1];
#if 1
out << "\n#include <" << basename << ">\n\n";
#else
out << "\n";
out << "#include <d3d12.h>\n";
out << "#include <dxgi1_5.h>\n";
out << "#include <d3dcompiler.h>\n\n";
#endif
out << header;
out.close();
return 0;
}

View File

@ -0,0 +1,30 @@
Program <- (Function / Comment / Line)* EndOfFile
Function <- _ ReturnType _ '(' _ FunctionName _ ')'_ Parameters
Parameters <- '('_ This _ ','? _ ( _ Param _ ','?)*_ ');'
FunctionName <- CallType _ '*' _ <Name>
This <- Type _ 'This'
Param <- InOut? _ Type _ Name _ ArraySize?
ReturnType <- <Type>
Type <- (TypeQualifier _)? Name Pointer?
TypeQualifier <- 'const'
~CallType <- '__export'? ('STDMETHODCALLTYPE' / 'STDMETHODVCALLTYPE' / 'STDAPICALLTYPE' / 'STDAPIVCALLTYPE' / '__cdecl' / '__stdcall')
~InOut <- '_'Name
ArraySize <- '[' _ <Number?> _ ']'
Pointer <- _<('*'/'const '/'const')+>
Name <- <([a-z]/[A-Z]/'_'/[0-9])+>
Number <- <[0-9]+>
~Line <- <(!EndOfLine !EndOfFile .)*> (EndOfLine / EndOfFile)
~EndOfStatement <- ';'
~EndOfLine <- '\r\n' / '\n' / '\r'
EndOfFile <- !.
End <- EndOfLine / EndOfFile
~_ <- (Comment / [ \t\r\n])*
Indent <- [ \t]
~Space <- [ \t]
Comment <- [ \t]*<('/*' (!'*/' .)* '*/' / '//') Line>

View File

@ -26,13 +26,13 @@ void DisassemblePPCRange(void *start, void *end, void* printf_func, void* GetSym
/* #define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0) */
#define DEBUG_LINE() do{printf("%s:%4d %s().\n", __FILE__, __LINE__, __FUNCTION__);fflush(stdout);}while(0)
#define DEBUG_STR(X) printf( "%s: %s\n", #X, (char*)(X))
#define DEBUG_VAR(X) printf( "%-20s: 0x%08" PRIX32 "\n", #X, (uint32_t)(X))
#define DEBUG_VAR2(X) printf( "%-20s: 0x%08" PRIX32 " (%i)\n", #X, (uint32_t)(X), (int)(X))
#define DEBUG_INT(X) printf( "%-20s: %10" PRIi32 "\n", #X, (int32_t)(X))
#define DEBUG_FLOAT(X) printf( "%-20s: %10.3f\n", #X, (float)(X))
#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016" PRIX64 "\n", (uint64_t)(X))
#define DEBUG_MAGIC(X) printf( "%-20s: '%c''%c''%c''%c' (0x%08X)\n", #X, (u32)(X)>>24, (u32)(X)>>16, (u32)(X)>>8, (u32)(X),(u32)(X))
#define DEBUG_STR(X) do{printf( "%s: %s\n", #X, (char*)(X));fflush(stdout);}while(0)
#define DEBUG_VAR(X) do{printf( "%-20s: 0x%08" PRIX32 "\n", #X, (uint32_t)(X));fflush(stdout);}while(0)
#define DEBUG_VAR2(X) do{printf( "%-20s: 0x%08" PRIX32 " (%i)\n", #X, (uint32_t)(X), (int)(X));fflush(stdout);}while(0)
#define DEBUG_INT(X) do{printf( "%-20s: %10" PRIi32 "\n", #X, (int32_t)(X));fflush(stdout);}while(0)
#define DEBUG_FLOAT(X) do{printf( "%-20s: %10.3f\n", #X, (float)(X));fflush(stdout);}while(0)
#define DEBUG_VAR64(X) do{printf( "%-20s: 0x%016" PRIX64 "\n", #X, (uint64_t)(X));fflush(stdout);}while(0)
#define DEBUG_MAGIC(X) do{printf( "%-20s: '%c''%c''%c''%c' (0x%08X)\n", #X, (u32)(X)>>24, (u32)(X)>>16, (u32)(X)>>8, (u32)(X),(u32)(X));fflush(stdout);}while(0)
/* #define DEBUG_ERROR(X) do{if(X)dump_result_value(X);}while(0) */
#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H"