<commit_before>import sys
import CppHeaderParser
import os
import errno
import re
from zipfile import *
import fnmatch
import re

def mkdir_p(path): # Same effect as mkdir -p, create dir and all necessary parent dirs
	try:
		os.makedirs(path)
	except OSError as e:
		if e.errno == errno.EEXIST: # Dir already exists; not really an error
			pass
		else: raise

# Note we expect className to be a valid string
def template_returnPtrLookup(prefix, className, ptr):
	out = ""
	out += "%sif _G[\"__ptr_lookup\"][%s][%s] ~= nil then\n" % (prefix, className, ptr)
	out += "%s\treturn _G[\"__ptr_lookup\"][%s][%s]\n" % (prefix, className, ptr)
	out += "%selse\n" % (prefix)
	out += "%s\t_G[\"__ptr_lookup\"][%s][%s] = _G[%s](\"__skip_ptr__\")\n" % (prefix, className, ptr, className)
	out += "%s\t_G[\"__ptr_lookup\"][%s][%s].__ptr = %s\n" % (prefix, className, ptr, ptr)
	out += "%s\treturn _G[\"__ptr_lookup\"][%s][%s]\n" % (prefix, className, ptr)
	out += "%send\n" % (prefix)
	return out
	
def template_quote(str):
	return "\"%s\"" % str;

# FIXME: Some "unsigned int *" functions are still being generated on the polycode API?
def typeFilter(ty):
	ty = ty.replace("Polycode::", "")
	ty = ty.replace("std::", "")
	ty = ty.replace("const", "")
	ty = ty.replace("&", "")
	ty = re.sub(r'^.*\sint\s*$', 'int', ty) # eg "unsigned int"
	ty = re.sub(r'^.*\slong\s*$', 'int', ty)
	ty = re.sub(r'^.*\sfloat\s*$', 'Number', ty)
	ty = re.sub(r'^.*\sdouble\s*$', 'Number', ty) # eg "long double"
	ty = ty.replace("unsigned", "int")
	ty = ty.replace("long", "int")
	ty = ty.replace("float", "Number")
	ty = ty.replace("double", "Number")
	ty = ty.replace(" ", "") # Not very safe!
	return ty

def createLUABindings(inputPath, prefix, mainInclude, libSmallName, libName, apiPath, apiClassPath, includePath, sourcePath, inheritInModuleFiles):
	wrappersHeaderOut = "" # Def: Global C++ *LUAWrappers.h
	cppRegisterOut = "" # Def: Global C++ *LUA.cpp
	
	luaIndexOut = "" # Def: Global Lua everything-gets-required-from-this-file file
	
	# Header boilerplate for wrappersHeaderOut and cppRegisterOut
	cppRegisterOut += "#include \"%sLUA.h\"\n" % (prefix)
	cppRegisterOut += "#include \"%sLUAWrappers.h\"\n" % (prefix)
	cppRegisterOut += "#include \"PolyCoreServices.h\"\n\n"
	cppRegisterOut += "using namespace Polycode;\n\n"
	cppRegisterOut += "int luaopen_%s(lua_State *L) {\n" % (prefix)
	if prefix != "Polycode":
		cppRegisterOut += "CoreServices *inst = (CoreServices*)lua_topointer(L, 1);\n"
		cppRegisterOut += "CoreServices::setInstance(inst);\n"
	cppRegisterOut += "\tstatic const struct luaL_reg %sLib [] = {" % (libSmallName)
	
	wrappersHeaderOut += "#pragma once\n\n"

	wrappersHeaderOut += "extern \"C\" {\n\n"
	wrappersHeaderOut += "#include <stdio.h>\n"
	wrappersHeaderOut += "#include \"lua.h\"\n"
	wrappersHeaderOut += "#include \"lualib.h\"\n"
	wrappersHeaderOut += "#include \"lauxlib.h\"\n"
	wrappersHeaderOut += "} // extern \"C\" \n\n"

	# Get list of headers to create bindings from
	inputPathIsDir = os.path.isdir(inputPath)
	if inputPathIsDir:
		files = os.listdir(inputPath)
	else:
		files = []
		with open(inputPath) as f:
			for line in f.readlines():
				files.append(line.strip()) # Strip whitespace, path/
	filteredFiles = []
	for fileName in files:
		if inputPathIsDir:
			fileName = "%s/%s" % (inputPath, fileName)
		head, tail = os.path.split(fileName)
		ignore = ["PolyGLSLProgram", "PolyGLSLShader", "PolyGLSLShaderModule", "PolyWinCore", "PolyCocoaCore", "PolyAGLCore", "PolySDLCore", "Poly_iPhone", "PolyGLES1Renderer", "PolyGLRenderer", "tinyxml", "tinystr", "OpenGLCubemap", "PolyiPhoneCore", "PolyGLES1Texture", "PolyGLTexture", "PolyGLVertexBuffer", "PolyThreaded", "PolyGLHeaders", "GLee", "PolyPeer", "PolySocket", "PolyClient", "PolyServer", "PolyServerWorld"]
		if tail.split(".")[1] == "h" and tail.split(".")[0] not in ignore:
			filteredFiles.append(fileName)
			wrappersHeaderOut += "#include \"%s\"\n" % (tail)

	wrappersHeaderOut += "\nusing namespace std;\n\n"
	wrappersHeaderOut += "\nnamespace Polycode {\n\n"
	
	# Special case: If we are building the Polycode library itself, inject the LuaEventHandler class.
	# Note: so that event callbacks can work, any object inheriting from EventHandler will secretly
	# be modified to actually inherit from LuaEventHandler instead.
	if prefix == "Polycode":
		wrappersHeaderOut += "class LuaEventHandler : public EventHandler {\n"
		wrappersHeaderOut += "public:\n"
		wrappersHeaderOut += "	LuaEventHandler() : EventHandler() {}\n"
		wrappersHeaderOut += "	void handleEvent(Event *e) {\n"
		wrappersHeaderOut += "		lua_rawgeti( L, LUA_REGISTRYINDEX, wrapperIndex );\n"
		wrappersHeaderOut += "		lua_getfield(L, -1, \"__handleEvent\");\n"
		wrappersHeaderOut += "		lua_rawgeti( L, LUA_REGISTRYINDEX, wrapperIndex );\n"
		wrappersHeaderOut += "		lua_pushlightuserdata(L, e);\n"
		wrappersHeaderOut += "		if(lua_pcall(L, 2, 0, 0) != 0) {\n"
		wrappersHeaderOut += "			const char *msg = lua_tostring(L, -1);\n"
		wrappersHeaderOut += "			lua_getfield(L, LUA_GLOBALSINDEX, \"__customError\");\n"
		wrappersHeaderOut += "			lua_pushstring(L, msg);\n"
		wrappersHeaderOut += "			lua_call(L, 1, 0);\n"
		wrappersHeaderOut += "		}\n"
		wrappersHeaderOut += "	}\n"
		wrappersHeaderOut += "	int wrapperIndex;\n"
		wrappersHeaderOut += "	lua_State *L;\n"
		wrappersHeaderOut += "};\n\n"
	
	# Iterate, process each input file
	for fileName in filteredFiles:
		# "Package owned" classes that ship with Polycode
		inheritInModule = ["PhysicsSceneEntity", "CollisionScene", "CollisionSceneEntity"]
		
		# A file or comma-separated list of files can be given to specify classes which are "package owned"
		# and should not be inherited out of Polycode/. The files should contain one class name per line,
		# and the class name may be prefixed with a path (which will be ignored).
		if inheritInModuleFiles:
			for moduleFileName in inheritInModuleFiles.split(","):
				with open(moduleFileName) as f:
					for line in f.readlines():
						inheritInModule.append(line.strip().split("/",1)[-1]) # Strip whitespace, path/
		
		print "Parsing %s" % fileName
		try: # One input file parse.
			f = open(fileName) # Def: Input file handle
			contents = f.read().replace("_PolyExport", "") # Def: Input file contents, strip out "_PolyExport"
			cppHeader = CppHeaderParser.CppHeader(contents, "string") # Def: Input file contents, parsed structure
			ignore_classes = ["PolycodeShaderModule", "Object", "Threaded", "OpenGLCubemap"]

			# Iterate, check each class in this file.
			for ckey in cppHeader.classes: 
				print ">> Parsing class %s" % ckey
				c = cppHeader.classes[ckey] # Def: The class structure

				luaClassBindingOut = "" # Def: The local lua file to generate for this class.
				inherits = False
				parentClass = ""
				if len(c["inherits"]) > 0: # Does this class have parents?
					if c["inherits"][0]["class"] not in ignore_classes:

						if c["inherits"][0]["class"] in inheritInModule: # Parent class is in this module
							luaClassBindingOut += "require \"%s/%s\"\n\n" % (prefix, c["inherits"][0]["class"])
						else: # Parent class is in Polycore
							luaClassBindingOut += "require \"Polycode/%s\"\n\n" % (c["inherits"][0]["class"])

						if (ckey == "ScreenParticleEmitter" or ckey == "SceneParticleEmitter"):
							luaClassBindingOut += "require \"Polycode/ParticleEmitter\"\n\n"

						luaClassBindingOut += "class \"%s\" (%s)\n\n" % (ckey, c["inherits"][0]["class"])
						parentClass = c["inherits"][0]["class"]
						inherits = True
				if inherits == False: # Class does not have parents
					luaClassBindingOut += "class \"%s\"\n\n" % ckey

				if ckey in ignore_classes:
					continue

				if len(c["methods"]["public"]) < 2: # Used to, this was a continue.
					print("Warning: Lua-binding class with less than two methods")
					continue # FIXME: Remove this, move any non-compileable classes into ignore_classes

				parsed_methods = [] # Def: List of discovered methods
				ignore_methods = ["readByte32", "readByte16", "getCustomEntitiesByType", "Core", "Renderer", "Shader", "Texture", "handleEvent", "secondaryHandler", "getSTLString"]
				luaClassBindingOut += "\n\n"

				classProperties = [] # Def: List of found property structures ("properties" meaning "data members")
				for pp in c["properties"]["public"]:
					pp["type"] = pp["type"].replace("Polycode::", "")
					pp["type"] = pp["type"].replace("std::", "")
					if pp["type"].find("POLYIGNORE") != -1:
						continue
					if pp["type"].find("static ") != -1: # If static. FIXME: Static doesn't work?
						if "defaltValue" in pp: # FIXME: defaltValue is misspelled.
							luaClassBindingOut += "%s = %s\n" % (pp["name"], pp["defaltValue"])
					else: # FIXME: Nonstatic method ? variable ?? found.
						#there are some bugs in the class parser that cause it to return junk
						if pp["type"].find("*") == -1 and pp["type"].find("vector") == -1 and pp["name"] != "setScale" and pp["name"] != "setPosition" and pp["name"] != "BUFFER_CACHE_PRECISION" and not pp["name"].isdigit():
							classProperties.append(pp)

				# Iterate over properties, creating getters
				pidx = 0 # Def: Count of properties processed so far
<commit_msg>const static members from C++ are now set in the metatable of the class (ScreenShape.SHAPE_RECT instead of SHAPE_RECT)<commit_after>import sys
import CppHeaderParser
import os
import errno
import re
from zipfile import *
import fnmatch
import re

def mkdir_p(path): # Same effect as mkdir -p, create dir and all necessary parent dirs
	try:
		os.makedirs(path)
	except OSError as e:
		if e.errno == errno.EEXIST: # Dir already exists; not really an error
			pass
		else: raise

# Note we expect className to be a valid string
def template_returnPtrLookup(prefix, className, ptr):
	out = ""
	out += "%sif _G[\"__ptr_lookup\"][%s][%s] ~= nil then\n" % (prefix, className, ptr)
	out += "%s\treturn _G[\"__ptr_lookup\"][%s][%s]\n" % (prefix, className, ptr)
	out += "%selse\n" % (prefix)
	out += "%s\t_G[\"__ptr_lookup\"][%s][%s] = _G[%s](\"__skip_ptr__\")\n" % (prefix, className, ptr, className)
	out += "%s\t_G[\"__ptr_lookup\"][%s][%s].__ptr = %s\n" % (prefix, className, ptr, ptr)
	out += "%s\treturn _G[\"__ptr_lookup\"][%s][%s]\n" % (prefix, className, ptr)
	out += "%send\n" % (prefix)
	return out
	
def template_quote(str):
	return "\"%s\"" % str;

# FIXME: Some "unsigned int *" functions are still being generated on the polycode API?
def typeFilter(ty):
	ty = ty.replace("Polycode::", "")
	ty = ty.replace("std::", "")
	ty = ty.replace("const", "")
	ty = ty.replace("&", "")
	ty = re.sub(r'^.*\sint\s*$', 'int', ty) # eg "unsigned int"
	ty = re.sub(r'^.*\slong\s*$', 'int', ty)
	ty = re.sub(r'^.*\sfloat\s*$', 'Number', ty)
	ty = re.sub(r'^.*\sdouble\s*$', 'Number', ty) # eg "long double"
	ty = ty.replace("unsigned", "int")
	ty = ty.replace("long", "int")
	ty = ty.replace("float", "Number")
	ty = ty.replace("double", "Number")
	ty = ty.replace(" ", "") # Not very safe!
	return ty

def createLUABindings(inputPath, prefix, mainInclude, libSmallName, libName, apiPath, apiClassPath, includePath, sourcePath, inheritInModuleFiles):
	wrappersHeaderOut = "" # Def: Global C++ *LUAWrappers.h
	cppRegisterOut = "" # Def: Global C++ *LUA.cpp
	
	luaIndexOut = "" # Def: Global Lua everything-gets-required-from-this-file file
	
	# Header boilerplate for wrappersHeaderOut and cppRegisterOut
	cppRegisterOut += "#include \"%sLUA.h\"\n" % (prefix)
	cppRegisterOut += "#include \"%sLUAWrappers.h\"\n" % (prefix)
	cppRegisterOut += "#include \"PolyCoreServices.h\"\n\n"
	cppRegisterOut += "using namespace Polycode;\n\n"
	cppRegisterOut += "int luaopen_%s(lua_State *L) {\n" % (prefix)
	if prefix != "Polycode":
		cppRegisterOut += "CoreServices *inst = (CoreServices*)lua_topointer(L, 1);\n"
		cppRegisterOut += "CoreServices::setInstance(inst);\n"
	cppRegisterOut += "\tstatic const struct luaL_reg %sLib [] = {" % (libSmallName)
	
	wrappersHeaderOut += "#pragma once\n\n"

	wrappersHeaderOut += "extern \"C\" {\n\n"
	wrappersHeaderOut += "#include <stdio.h>\n"
	wrappersHeaderOut += "#include \"lua.h\"\n"
	wrappersHeaderOut += "#include \"lualib.h\"\n"
	wrappersHeaderOut += "#include \"lauxlib.h\"\n"
	wrappersHeaderOut += "} // extern \"C\" \n\n"

	# Get list of headers to create bindings from
	inputPathIsDir = os.path.isdir(inputPath)
	if inputPathIsDir:
		files = os.listdir(inputPath)
	else:
		files = []
		with open(inputPath) as f:
			for line in f.readlines():
				files.append(line.strip()) # Strip whitespace, path/
	filteredFiles = []
	for fileName in files:
		if inputPathIsDir:
			fileName = "%s/%s" % (inputPath, fileName)
		head, tail = os.path.split(fileName)
		ignore = ["PolyGLSLProgram", "PolyGLSLShader", "PolyGLSLShaderModule", "PolyWinCore", "PolyCocoaCore", "PolyAGLCore", "PolySDLCore", "Poly_iPhone", "PolyGLES1Renderer", "PolyGLRenderer", "tinyxml", "tinystr", "OpenGLCubemap", "PolyiPhoneCore", "PolyGLES1Texture", "PolyGLTexture", "PolyGLVertexBuffer", "PolyThreaded", "PolyGLHeaders", "GLee", "PolyPeer", "PolySocket", "PolyClient", "PolyServer", "PolyServerWorld"]
		if tail.split(".")[1] == "h" and tail.split(".")[0] not in ignore:
			filteredFiles.append(fileName)
			wrappersHeaderOut += "#include \"%s\"\n" % (tail)

	wrappersHeaderOut += "\nusing namespace std;\n\n"
	wrappersHeaderOut += "\nnamespace Polycode {\n\n"
	
	# Special case: If we are building the Polycode library itself, inject the LuaEventHandler class.
	# Note: so that event callbacks can work, any object inheriting from EventHandler will secretly
	# be modified to actually inherit from LuaEventHandler instead.
	if prefix == "Polycode":
		wrappersHeaderOut += "class LuaEventHandler : public EventHandler {\n"
		wrappersHeaderOut += "public:\n"
		wrappersHeaderOut += "	LuaEventHandler() : EventHandler() {}\n"
		wrappersHeaderOut += "	void handleEvent(Event *e) {\n"
		wrappersHeaderOut += "		lua_rawgeti( L, LUA_REGISTRYINDEX, wrapperIndex );\n"
		wrappersHeaderOut += "		lua_getfield(L, -1, \"__handleEvent\");\n"
		wrappersHeaderOut += "		lua_rawgeti( L, LUA_REGISTRYINDEX, wrapperIndex );\n"
		wrappersHeaderOut += "		lua_pushlightuserdata(L, e);\n"
		wrappersHeaderOut += "		if(lua_pcall(L, 2, 0, 0) != 0) {\n"
		wrappersHeaderOut += "			const char *msg = lua_tostring(L, -1);\n"
		wrappersHeaderOut += "			lua_getfield(L, LUA_GLOBALSINDEX, \"__customError\");\n"
		wrappersHeaderOut += "			lua_pushstring(L, msg);\n"
		wrappersHeaderOut += "			lua_call(L, 1, 0);\n"
		wrappersHeaderOut += "		}\n"
		wrappersHeaderOut += "	}\n"
		wrappersHeaderOut += "	int wrapperIndex;\n"
		wrappersHeaderOut += "	lua_State *L;\n"
		wrappersHeaderOut += "};\n\n"
	
	# Iterate, process each input file
	for fileName in filteredFiles:
		# "Package owned" classes that ship with Polycode
		inheritInModule = ["PhysicsSceneEntity", "CollisionScene", "CollisionSceneEntity"]
		
		# A file or comma-separated list of files can be given to specify classes which are "package owned"
		# and should not be inherited out of Polycode/. The files should contain one class name per line,
		# and the class name may be prefixed with a path (which will be ignored).
		if inheritInModuleFiles:
			for moduleFileName in inheritInModuleFiles.split(","):
				with open(moduleFileName) as f:
					for line in f.readlines():
						inheritInModule.append(line.strip().split("/",1)[-1]) # Strip whitespace, path/
		
		print "Parsing %s" % fileName
		try: # One input file parse.
			f = open(fileName) # Def: Input file handle
			contents = f.read().replace("_PolyExport", "") # Def: Input file contents, strip out "_PolyExport"
			cppHeader = CppHeaderParser.CppHeader(contents, "string") # Def: Input file contents, parsed structure
			ignore_classes = ["PolycodeShaderModule", "Object", "Threaded", "OpenGLCubemap"]

			# Iterate, check each class in this file.
			for ckey in cppHeader.classes: 
				print ">> Parsing class %s" % ckey
				c = cppHeader.classes[ckey] # Def: The class structure

				luaClassBindingOut = "" # Def: The local lua file to generate for this class.
				inherits = False
				parentClass = ""
				if len(c["inherits"]) > 0: # Does this class have parents?
					if c["inherits"][0]["class"] not in ignore_classes:

						if c["inherits"][0]["class"] in inheritInModule: # Parent class is in this module
							luaClassBindingOut += "require \"%s/%s\"\n\n" % (prefix, c["inherits"][0]["class"])
						else: # Parent class is in Polycore
							luaClassBindingOut += "require \"Polycode/%s\"\n\n" % (c["inherits"][0]["class"])

						if (ckey == "ScreenParticleEmitter" or ckey == "SceneParticleEmitter"):
							luaClassBindingOut += "require \"Polycode/ParticleEmitter\"\n\n"

						luaClassBindingOut += "class \"%s\" (%s)\n\n" % (ckey, c["inherits"][0]["class"])
						parentClass = c["inherits"][0]["class"]
						inherits = True
				if inherits == False: # Class does not have parents
					luaClassBindingOut += "class \"%s\"\n\n" % ckey

				if ckey in ignore_classes:
					continue

				if len(c["methods"]["public"]) < 2: # Used to, this was a continue.
					print("Warning: Lua-binding class with less than two methods")
					continue # FIXME: Remove this, move any non-compileable classes into ignore_classes

				parsed_methods = [] # Def: List of discovered methods
				ignore_methods = ["readByte32", "readByte16", "getCustomEntitiesByType", "Core", "Renderer", "Shader", "Texture", "handleEvent", "secondaryHandler", "getSTLString"]
				luaClassBindingOut += "\n\n"

				classProperties = [] # Def: List of found property structures ("properties" meaning "data members")
				for pp in c["properties"]["public"]:
					pp["type"] = pp["type"].replace("Polycode::", "")
					pp["type"] = pp["type"].replace("std::", "")
					if pp["type"].find("POLYIGNORE") != -1:
						continue
					if pp["type"].find("static ") != -1: # If static. FIXME: Static doesn't work?
						if "defaltValue" in pp: # FIXME: defaltValue is misspelled.
							luaClassBindingOut += "%s.%s = %s\n" % (ckey, pp["name"], pp["defaltValue"])
					else: # FIXME: Nonstatic method ? variable ?? found.
						#there are some bugs in the class parser that cause it to return junk
						if pp["type"].find("*") == -1 and pp["type"].find("vector") == -1 and pp["name"] != "setScale" and pp["name"] != "setPosition" and pp["name"] != "BUFFER_CACHE_PRECISION" and not pp["name"].isdigit():
							classProperties.append(pp)

				# Iterate over properties, creating getters
				pidx = 0 # Def: Count of properties processed so far

{'fraction_non_alphanumeric': 0.16470333945747326, 'fraction_numerical': 0.003458337836377391, 'mean_word_length': 4.283185840707965, 'pattern_counts': {'":': 4, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2272508', 'n_tokens_mistral': 6839, 'n_tokens_neox': 6284, 'n_words': 1712}