Skip to content

Commit

Permalink
Update for windows
Browse files Browse the repository at this point in the history
  • Loading branch information
Victorious3 committed Jun 4, 2023
1 parent ca0d225 commit 97d0cca
Show file tree
Hide file tree
Showing 13 changed files with 20,249 additions and 14,460 deletions.
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def download():
Path(archive).unlink()

def build(extra):
args = [exe_file("bin/princess"), "-d", "-Isrc", "--buildfolder=build", "--outfile", exe_file("bin/princess2"), "src/main.pr"]
args = [exe_file("bin/princess"), "-d", "--no-incremental", "-Isrc", "--buildfolder=build", "--outfile", exe_file("bin/princess2"), "src/main.pr"]
if sys.platform == "win32":
args += WIN_ARGS
else:
Expand Down
30 changes: 30 additions & 0 deletions include/cstd.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,36 @@
%EXCLUDE __builtin_fabsf __builtin_inff __builtin_fabs __builtin_inf __builtin_fabsl __builtin_infl longjmperror
%EXCLUDE __va_start _sopen_s_nolock
%EXCLUDE __builtin_bswap32 __builtin_bswap64

Windows specific
%EXCLUDE vfwprintf _vfwprintf_s_l vfwprintf_s _vfwprintf_p_l _vfwprintf_p _vwprintf_l vwprintf _vwprintf_s_l vwprintf_s
%EXCLUDE _vwprintf_p_l _vwprintf_p _fwprintf_l _fwprintf_s_l fwprintf_s _fwprintf_p_l _fwprintf_p _wprintf_l wprintf
%EXCLUDE _wprintf_s_l wprintf_s _wprintf_p_l _wprintf_p _vfwscanf_l vfwscanf _vfwscanf_s_l vfwscanf_s _vwscanf_l vwscanf
%EXCLUDE _vwscanf_s_l vwscanf_s _fwscanf_l fwscanf _fwscanf_s_l fwscanf_s _wscanf_l wscanf _wscanf_s_l wscanf_s _vsnwprintf_l
%EXCLUDE _vsnwprintf_s_l _vsnwprintf_s _snwprintf _vsnwprintf _vswprintf_c _vswprintf_l __vswprintf_l _vswprintf _vswprintf
%EXCLUDE vswprintf vswprintf _vswprintf_s_l vswprintf_s _vswprintf_p_l _vswprintf_p _vscwprintf_l _vscwprintf _vscwprintf_p_l
%EXCLUDE _vscwprintf_p _swprintf __swprintf_l _swprintf_l _swprintf _swprintf _swprintf_s_l swprintf_s _swprintf_p_l _swprintf_p
%EXCLUDE _swprintf_c_l _swprintf_c _snwprintf_l _snwprintf_s_l _snwprintf_s _scwprintf_l _scwprintf _scwprintf_p_l
%EXCLUDE _scwprintf_p _vswscanf_l vswscanf _vswscanf_s_l vswscanf_s _vsnwscanf_l _vsnwscanf_s_l _swscanf_l swscanf
%EXCLUDE _swscanf_s_l swscanf_s _snwscanf_l _snwscanf _snwscanf_s_l _snwscanf_s _vfprintf_s_l vfprintf_s _vfprintf_p_l
%EXCLUDE _vfprintf_p _vprintf_l _vprintf_s_l vprintf_s _vprintf_p_l _vprintf_p _fprintf_l _fprintf_s_l fprintf_s
%EXCLUDE _fprintf_p_l _fprintf_p _printf_l _printf_s_l printf_s _printf_p_l _printf_p _vfscanf_s_l vfscanf_s _vscanf_l
%EXCLUDE _vscanf_s_l vscanf_s _fscanf_l _fscanf_s_l fscanf_s _scanf_l _scanf_s_l scanf_s vsprintf_s _vsprintf_p_l _vsprintf_p
%EXCLUDE _vsnprintf_s_l _vsnprintf_s _vsnprintf_s vsnprintf_s vsnprintf_s _vscprintf_l _vscprintf _vscprintf_p_l _vscprintf_p
%EXCLUDE _vsnprintf_c_l _vsnprintf_c _sprintf_l _sprintf_s_l _sprintf_p_l _sprintf_p _snprintf_l _snprintf_c_l _snprintf_c
%EXCLUDE _snprintf_s_l _snprintf_s _scprintf_l _scprintf _scprintf_p_l _scprintf_p _vsscanf_s_l vsscanf_s _sscanf_l
%EXCLUDE _sscanf_s_l sscanf_s _snscanf_l _snscanf _snscanf_s_l _snscanf_s wcsnlen_s _wcstok strnlen_s _wctime_s timespec_get
%EXCLUDE ctime_s gmtime_s localtime_s _chgsignl _copysignl _hypotl __ascii_iswdigit _vcwprintf_l _vcwprintf _vcwprintf_s_l
%EXCLUDE _vcwprintf_s _vcwprintf_p_l _vcwprintf_p _cwprintf_l _cwprintf _cwprintf_s_l _cwprintf_s _cwprintf_p_l _cwprintf_p
%EXCLUDE _vcwscanf_l _vcwscanf _vcwscanf_s_l _vcwscanf_s _cwscanf_l _cwscanf _cwscanf_s_l _cwscanf_s _vcprintf_l _vcprintf
%EXCLUDE _vcprintf_s_l _vcprintf_s _vcprintf_p_l _vcprintf_p _cprintf_l _cprintf _cprintf _cprintf_s_l _cprintf_s _cprintf_p_l
%EXCLUDE _cprintf_p _vcscanf_l _vcscanf _vcscanf_s_l _vcscanf_s _cscanf_l _cscanf _cscanf _cscanf_s_l _cscanf_s cprintf cprintf cscanf cscanf

Inline functions
%EXCLUDE __acrt_locale_get_ctype_array_value __ascii_iswalpha __ascii_toupper time __ascii_towlower difftime sprintf_s
%EXCLUDE _vsscanf_l localtime _chvalidchk_l mktime _mkgmtime memcpy_s _vfscanf_l _vsprintf_l __acrt_get_locale_data_prefix
%EXCLUDE _vsprintf_s_l fwprintf __ascii_tolower _vfprintf_l __ascii_towupper __threadid _ischartype_l _wctime gmtime
%EXCLUDE __threadhandle _vsnprintf_l ctime __local_stdio_printf_options _vfwprintf_l swprintf memmove_s __local_stdio_scanf_options _vswprintf_c_l
*/

#include <stdlib.h>
Expand Down
102 changes: 70 additions & 32 deletions include/gencstd.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ def print_references(self, file: File):
if self.displayname in file.has_declared or self.displayname in file.has_printed: return
else: file.has_declared.add(self.displayname)

print(f"export type {self.displayname}", file = file.fp)
if self.displayname and "()" not in self.displayname:
print(f"export type {self.displayname}", file = file.fp)

class IncompleteTypedef(Type):
def __init__(self, name: str):
Expand Down Expand Up @@ -192,14 +193,15 @@ def print_references(self, file: File):
self = file.TAGGED[self.name]

for f in self.fields:
f.type.print_references(file)
if f.type:
f.type.print_references(file)

if not self.fields: return
if not self.displayname in file.has_printed:
file.has_printed.add(self.displayname)
else: return

if self.name:
if self.displayname:
print(f"export type {self.displayname}", file = file.fp, end = "")
if self.fields:
print(f" = {self.to_definition(file)}", file = file.fp)
Expand All @@ -215,7 +217,7 @@ def to_definition(self, file: File) -> str:
if self.fields:
res = "struct { "
for field in self.fields:
res += field.to_definition(file) + "; "
if field.type: res += field.to_definition(file) + "; "
res += "}"
return res

Expand All @@ -229,7 +231,7 @@ def to_definition(self, file: File) -> str:
if self.fields:
res = "struct #union { "
for field in self.fields:
res += field.to_definition(file) + "; "
if field.type: res += field.to_definition(file) + "; "
res += "}"
return res

Expand Down Expand Up @@ -265,7 +267,7 @@ def print_references(self, file: File):
file.has_printed.add(self.displayname)
else: return

if self.name and not is_anonymous(self.name):
if self.displayname and not is_anonymous(self.name):
print(f"export type {self.displayname}", file = file.fp, end = "")
if self.fields:
print(f" = {self.to_definition(file)}", file = file.fp)
Expand Down Expand Up @@ -418,10 +420,22 @@ def parse_struct(name: str, inner: clang.Type, file: File, lookup: bool = False)

fields = []
field: clang.Cursor
index = 0
for field in children:
if field.kind == clang.CursorKind.STRUCT_DECL:
if len(list(field.get_children())) == 0: continue
fields.append(Field(parse_type(field.type, file, is_in_struct = True), field.spelling, field.is_bitfield(), field.get_bitfield_width()))
field_type = parse_type(field.type, file, is_in_struct = True)
if not field_type: return None

exists = True
spelling = field.spelling
if not spelling:
spelling = "_" + str(index)
if type(field_type) == IncompleteType:
field_type = None

fields.append(Field(field_type, spelling, field.is_bitfield(), field.get_bitfield_width()))
index += 1

res = None
if declaration.kind == clang.CursorKind.STRUCT_DECL:
Expand Down Expand Up @@ -486,9 +500,24 @@ def parse_type(type: clang.Type, file: File, lookup: bool = False, is_in_struct:
elif type.kind == clang.TypeKind.INCOMPLETEARRAY:
return Pointer(parse_type(type.get_array_element_type(), file, lookup, is_in_struct))
elif type.kind == clang.TypeKind.TYPEDEF:
return file.TYPEDEFS[type.spelling]
spelling = type.spelling
# TODO This doesn't work properly
if spelling.startswith("const"):
spelling = spelling.replace("const", "", 1)
spelling = spelling.strip()
if spelling.startswith("__unaligned"):
spelling = spelling.replace("__unaligned", "", 1)
spelling = spelling.strip()
if spelling.startswith("volatile"):
spelling = spelling.replace("volatile", "", 1)
spelling = spelling.strip()

spelling = spelling.strip()
return file.TYPEDEFS[spelling]

return IncompleteType(type.spelling)

assert False, f"Invalid type! {type.kind}"
ALL_DEFINITIONS = {}

def process_module(name: str, *libs):
included = []
Expand Down Expand Up @@ -516,39 +545,45 @@ def process_module(name: str, *libs):
def extract(node: clang.Cursor):
if node.kind == clang.CursorKind.FUNCTION_DECL:
if node.is_static_method(): return

for token in node.get_tokens():
if token.spelling == "__inline" or token.spelling == "inline":
return

dllimport = False #TODO
dllimport = False
for child in node.get_children():
if child.kind == clang.CursorKind.DLLIMPORT_ATTR:
dllimport = True

name = node.spelling
args = []

for child in node.get_arguments():
if child.kind == clang.CursorKind.PARM_DECL:
tokens = list(child.get_tokens())
if len(tokens) == 2 and tokens[0].spelling == "size_t": #FIXME This is a hack, see https://github.com/sighingnow/libclang/issues/53
args.append((child.spelling, PRIMITIVES[clang.TypeKind.ULONG]))
spelling = escape_name(child.spelling)
if sys.platform == "linux" and len(tokens) == 2 and tokens[0].spelling == "size_t": #FIXME This is a hack, see https://github.com/sighingnow/libclang/issues/53
args.append((spelling, PRIMITIVES[clang.TypeKind.ULONG]))
else:
args.append((child.spelling, parse_type(child.type, file)))
args.append((spelling, parse_type(child.type, file)))

is_size_t = False #FIXME Same hack
for token in node.get_tokens():
if token.kind == clang.TokenKind.KEYWORD and token.spelling == "extern": continue
if token.spelling == "size_t": is_size_t = True
if token.spelling == "(": break

if is_size_t:
if is_size_t and sys.platform == "linux":
ret = PRIMITIVES[clang.TypeKind.ULONG]
else:
ret = parse_type(node.result_type, file)

file.GLOBALS[name] = FunctionDecl(name, ret, args, node.type.is_function_variadic(), dllimport)
elif node.kind == clang.CursorKind.VAR_DECL:
if node.storage_class == clang.StorageClass.EXTERN:
dllimport = False
for child in node.get_children():
if child.kind == clang.CursorKind.DLLIMPORT_ATTR:
dllimport = True

type = parse_type(node.type, file)
file.GLOBALS[node.spelling] = VarDecl(node.spelling, type, False)
file.GLOBALS[node.spelling] = VarDecl(node.spelling, type, dllimport)
elif node.kind == clang.CursorKind.TYPEDEF_DECL:
name = node.spelling
underlying = node.underlying_typedef_type
Expand Down Expand Up @@ -580,18 +615,19 @@ def extract(node: clang.Cursor):
elif node.kind == clang.CursorKind.MACRO_DEFINITION:
tokens = list(node.get_tokens())
if len(tokens) == 2 and tokens[1].kind == clang.TokenKind.LITERAL:
token = tokens[1]
if token.spelling.startswith('"') and token.spelling.endswith('"'):
s = token.spelling
s = re.sub(r"(?<!\\)\\(\d{1,3})", lambda o: f"\\x{ + int(o.group(1), base = 8):02x}", s)
file.GLOBALS[node.spelling] = ConstDecl(node.spelling, string, s)
elif token.spelling.isdigit():
file.GLOBALS[node.spelling] = ConstDecl(node.spelling, PRIMITIVES[clang.TypeKind.INT], token.spelling)
else:
try:
float(token.spelling)
file.GLOBALS[node.spelling] = ConstDecl(node.spelling, PRIMITIVES[clang.TypeKind.DOUBLE], token.spelling)
except ValueError: pass
if node.spelling != "true" and node.spelling != "false":
token = tokens[1]
if token.spelling.startswith('"') and token.spelling.endswith('"'):
s = token.spelling
s = re.sub(r"(?<!\\)\\(\d{1,3})", lambda o: f"\\x{ + int(o.group(1), base = 8):02x}", s)
file.GLOBALS[node.spelling] = ConstDecl(node.spelling, string, s)
elif token.spelling.isdigit():
file.GLOBALS[node.spelling] = ConstDecl(node.spelling, PRIMITIVES[clang.TypeKind.INT], token.spelling)
else:
try:
float(token.spelling)
file.GLOBALS[node.spelling] = ConstDecl(node.spelling, PRIMITIVES[clang.TypeKind.DOUBLE], token.spelling)
except ValueError: pass

index = clang.Index.create()
tu = index.parse(folder / f"{name}.h", options =
Expand All @@ -603,7 +639,8 @@ def extract(node: clang.Cursor):
extract(node)


file.GLOBALS = {k:v for k,v in file.GLOBALS.items() if k not in excluded}
file.GLOBALS = {k:v for k,v in file.GLOBALS.items() if k not in excluded and k not in ALL_DEFINITIONS }
ALL_DEFINITIONS.update(file.GLOBALS)

for type in file.TYPEDEFS.values():
type.print_references(file)
Expand All @@ -625,6 +662,7 @@ def extract(node: clang.Cursor):
print(f"export var __SYMBOLS: [{num_decls}; symbol::Symbol]", file = fp2)

def main():
clang.Config.set_library_file(r"C:\Users\Vic\Programming\llvm-project\build\Release\bin\libclang.dll")
if sys.platform != "win32":
process_module("linux")
process_module("bfd")
Expand Down
7 changes: 7 additions & 0 deletions include/windows.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
/*
%EXCLUDE WinMain wWinMain

Inline functions
%EXCLUDE GetProcessDefaultCpuSetMasks SymGetSourceFileTokenByTokenName SymGetSourceFileFromTokenByTokenName
%EXCLUDE GetNumaNodeProcessorMask2 SetThreadSelectedCpuSetMasks RegisterForTooltipDismissNotification QueueUserAPC2
%EXCLUDE EnableProcessOptionalXStateFeatures GetThreadSelectedCpuSetMasks GetMachineTypeAttributes SymGetSourceFileTokenByTokenNameW
%EXCLUDE SetProcessDefaultCpuSetMasks SetAdditionalForegroundBoostProcesses AreShortNamesEnabled GetTempPath2A GetTempPath2W
%EXCLUDE GetThreadEnabledXStateFeatures SymGetSourceFileFromTokenByTokenNameW StackWalk2
*/
#ifdef _WIN32
#include <Windows.h>
Expand Down
Loading

0 comments on commit 97d0cca

Please sign in to comment.