<commit_before>#!/usr/common/bin/python

# apiutil.py
#
# This file defines a bunch of utility functions for OpenGL API code
# generation.

import sys, string


#======================================================================

def CopyrightC( ):
	print """/* Copyright (c) 2001, Stanford University
	All rights reserved.

	See the file LICENSE.txt for information on redistributing this software. */
	"""

def CopyrightDef( ):
	print """; Copyright (c) 2001, Stanford University
	; All rights reserved.
	;
	; See the file LICENSE.txt for information on redistributing this software.
	"""



#======================================================================

class APIFunction:
	"""Class to represent a GL API function (name, return type,
	parameters, etc)."""
	def __init__(self):
		self.name = ''
		self.returnType = ''
		self.category = ''
		self.offset = -1
		self.alias = ''
		self.vectoralias = ''
		self.params = []
		self.paramlist = []
		self.paramvec = []
		self.paramaction = []
		self.paramprop = []
		self.paramset = []
		self.props = []
		self.chromium = []



def ProcessSpecFile(filename, userFunc):
	"""Open the named API spec file and call userFunc(record) for each record
	processed."""
	specFile = open(filename, "r")
	if not specFile:
		print "Error: couldn't open %s file!" % filename
		sys.exit()

	record = APIFunction()

	for line in specFile.readlines():

		# split line into tokens
		tokens = string.split(line)

		if len(tokens) > 0 and line[0] != '#':

			if tokens[0] == 'name':
				if record.name != '':
					# process the function now
					userFunc(record)
					# reset the record
					record = APIFunction()

				record.name = tokens[1]

			elif tokens[0] == 'return':
				record.returnType = string.join(tokens[1:], ' ')
			
			elif tokens[0] == 'param':
				name = tokens[1]
				type = string.join(tokens[2:], ' ')
				vecSize = 0
				record.params.append((name, type, vecSize))

			elif tokens[0] == 'paramprop':
				name = tokens[1]
				str = tokens[2:]
				enums = []
				for i in range(len(str)):
					enums.append(str[i]) 
				record.paramprop.append((name, enums))

			elif tokens[0] == 'paramlist':
				name = tokens[1]
				str = tokens[2:]
				list = []
				for i in range(len(str)):
					list.append(str[i]) 
				record.paramlist.append((name,list))

			elif tokens[0] == 'paramvec':
				name = tokens[1]
				str = tokens[2:]
				vec = []
				for i in range(len(str)):
					vec.append(str[i]) 
				record.paramvec.append((name,vec))

			elif tokens[0] == 'paramset':
				line = tokens[1:]
				result = []
				for i in range(len(line)):
					tset = line[i]
                                	if tset == '[':
                                        	nlist = []
                                	elif tset == ']':
                                        	result.append(nlist)
						nlist = []
                                	else:
                                        	nlist.append(tset)
				if result != []:
					record.paramset.append(result)

			elif tokens[0] == 'paramaction':
				name = tokens[1]
				str = tokens[2:]
				list = []
				for i in range(len(str)):
					list.append(str[i]) 
				record.paramaction.append((name,list))

			elif tokens[0] == 'category':
				record.category = tokens[1]

			elif tokens[0] == 'offset':
				if tokens[1] == '?':
					record.offset = -2
				else:
					record.offset = int(tokens[1])

			elif tokens[0] == 'alias':
				record.alias = tokens[1]

			elif tokens[0] == 'vectoralias':
				record.vectoralias = tokens[1]

			elif tokens[0] == 'props':
				record.props = tokens[1:]

			elif tokens[0] == 'chromium':
				record.chromium = tokens[1:]

			elif tokens[0] == 'vector':
				vecName = tokens[1]
				vecSize = int(tokens[2])
				for i in range(len(record.params)):
					(name, type, oldSize) = record.params[i]
					if name == vecName:
						record.params[i] = (name, type, vecSize)
						break

			else:
				print 'Invalid token %s after function %s' % (tokens[0], record.name)
			#endif
		#endif
	#endfor
	specFile.close()
#enddef





# Dictionary [name] of APIFunction:
__FunctionDict = {}

# Dictionary [name] of name
__VectorVersion = {}

# Reverse mapping of function name aliases
__ReverseAliases = {}


def AddFunction(record):
	assert not __FunctionDict.has_key(record.name)
	#if not "omit" in record.chromium:
	__FunctionDict[record.name] = record



def GetFunctionDict(specFile = ""):
	if not specFile:
		specFile = "../glapi_parser/APIspec.txt"
	if len(__FunctionDict) == 0:
		ProcessSpecFile(specFile, AddFunction)
		# Look for vector aliased functions
		for func in __FunctionDict.keys():
			va = __FunctionDict[func].vectoralias
			if va != '':
				__VectorVersion[va] = func
			#endif

			# and look for regular aliases (for glloader)
			a = __FunctionDict[func].alias
			if a:
				__ReverseAliases[a] = func
			#endif
		#endfor
	#endif
	return __FunctionDict


def GetAllFunctions(specFile = ""):
	"""Return sorted list of all functions known to Chromium."""
	d = GetFunctionDict(specFile)
	funcs = []
	for func in d.keys():
		rec = d[func]
		if not "omit" in rec.chromium:
			funcs.append(func)
	funcs.sort()
	return funcs
	

def GetDispatchedFunctions(specFile = ""):
	"""Return sorted list of all functions handled by SPU dispatch table."""
	d = GetFunctionDict(specFile)
	funcs = []
	for func in d.keys():
		rec = d[func]
		if (not "omit" in rec.chromium and
			not "stub" in rec.chromium and
			rec.alias == ''):
			funcs.append(func)
	funcs.sort()
	return funcs


#======================================================================

def ReturnType(funcName):
	"""Return the C return type of named function."""
	d = GetFunctionDict()
	return d[funcName].returnType


def Parameters(funcName):
	"""Return list of tuples (name, type, vecSize) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].params

def ParamAction(funcName):
	"""Return list of names of actions for testing."""
	d = GetFunctionDict()
	return d[funcName].paramaction

def ParamList(funcName):
	"""Return list of tuples (name, list of values) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].paramlist

def ParamVec(funcName):
	"""Return list of tuples (name, vector of values) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].paramvec

def ParamSet(funcName):
	"""Return list of tuples (name, list of values) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].paramset


def Properties(funcName):
	"""Return list of properties of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].props


def Category(funcName):
	"""Return the category of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].category


def ChromiumProps(funcName):
	"""Return list of Chromium-specific properties of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].chromium

def ParamProps(funcName):
	"""Return list of Parameter-specific properties of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].paramprop

def Alias(funcName):
	"""Return the function that the named function is an alias of.
	Ex: Alias('DrawArraysEXT') = 'DrawArrays'.
	"""
	d = GetFunctionDict()
	return d[funcName].alias


def ReverseAlias(funcName):
	"""Like Alias(), but the inverse."""
	d = GetFunctionDict()
	if funcName in __ReverseAliases.keys():
		return __ReverseAliases[funcName]
	else:
		return ''


def NonVectorFunction(funcName):
	"""Return the non-vector version of the given function, or ''.
	For example: NonVectorFunction("Color3fv") = "Color3f"."""
	d = GetFunctionDict()
	return d[funcName].vectoralias


def VectorFunction(funcName):
	"""Return the vector version of the given non-vector-valued function,
	or ''.
	For example: VectorVersion("Color3f") = "Color3fv"."""
	d = GetFunctionDict()
	if funcName in __VectorVersion.keys():
		return __VectorVersion[funcName]
	else:
		return ''


def GetCategoryWrapper(func_name):
	"""Return a C preprocessor token to test in order to wrap code.
	This handles extensions.
	Example: GetTestWrapper("glActiveTextureARB") = "CR_multitexture"
	Example: GetTestWrapper("glBegin") = ""
	"""
	cat = Category(func_name)
	if (cat == "1.0" or
		cat == "1.1" or
		cat == "1.2" or
		cat == "Chromium" or
		cat == "GL_chromium"):
		return ''
	elif cat[0] =='1':
		# i.e. OpenGL 1.3 or 1.4 or 1.5
		return "OPENGL_VERSION_" + string.replace(cat, ".", "_")
	else:
		assert cat != ''
		return string.replace(cat, "GL_", "")


def CanCompile(funcName):
	"""Return 1 if the function can be compiled into display lists, else 0."""
	d = GetFunctionDict()
	props = Properties(funcName)
	if ("nolist" in props or
		"get" in props or
		"setclient" in props or
		"useclient" in props):
		return 0
	else:
		return 1


def CanPack(funcName):
	"""Return 1 if the function can be packed, else 0."""
	d = GetFunctionDict()
	props = ChromiumProps(funcName)
	if ("pack" in props) or ("extpack" in props):
		return 1
	# check for packable alias
	alias = NonVectorFunction(funcName)
	if alias:
		props = ChromiumProps(alias)
		if ("pack" in props) or ("extpack" in props):
			return 1
	# check for vector version of packing function
	alias = VectorFunction(funcName)
	if alias:
		props = ChromiumProps(alias)
		if ("pack" in props) or ("extpack" in props):
			return 1
	return 0


def IsPointer(dataType):
	"""Determine if the datatype is a pointer.  Return 1 or 0."""
	if string.find(dataType, "*") == -1:
		return 0
	else:
		return 1


def PointerType(pointerType):
	"""Return the type of a pointer.
	Ex: PointerType('const GLubyte *') = 'GLubyte'
	"""<commit_msg>added FuncGetsState() function - but not used yet<commit_after>#!/usr/common/bin/python

# apiutil.py
#
# This file defines a bunch of utility functions for OpenGL API code
# generation.

import sys, string


#======================================================================

def CopyrightC( ):
	print """/* Copyright (c) 2001, Stanford University
	All rights reserved.

	See the file LICENSE.txt for information on redistributing this software. */
	"""

def CopyrightDef( ):
	print """; Copyright (c) 2001, Stanford University
	; All rights reserved.
	;
	; See the file LICENSE.txt for information on redistributing this software.
	"""



#======================================================================

class APIFunction:
	"""Class to represent a GL API function (name, return type,
	parameters, etc)."""
	def __init__(self):
		self.name = ''
		self.returnType = ''
		self.category = ''
		self.offset = -1
		self.alias = ''
		self.vectoralias = ''
		self.params = []
		self.paramlist = []
		self.paramvec = []
		self.paramaction = []
		self.paramprop = []
		self.paramset = []
		self.props = []
		self.chromium = []



def ProcessSpecFile(filename, userFunc):
	"""Open the named API spec file and call userFunc(record) for each record
	processed."""
	specFile = open(filename, "r")
	if not specFile:
		print "Error: couldn't open %s file!" % filename
		sys.exit()

	record = APIFunction()

	for line in specFile.readlines():

		# split line into tokens
		tokens = string.split(line)

		if len(tokens) > 0 and line[0] != '#':

			if tokens[0] == 'name':
				if record.name != '':
					# process the function now
					userFunc(record)
					# reset the record
					record = APIFunction()

				record.name = tokens[1]

			elif tokens[0] == 'return':
				record.returnType = string.join(tokens[1:], ' ')
			
			elif tokens[0] == 'param':
				name = tokens[1]
				type = string.join(tokens[2:], ' ')
				vecSize = 0
				record.params.append((name, type, vecSize))

			elif tokens[0] == 'paramprop':
				name = tokens[1]
				str = tokens[2:]
				enums = []
				for i in range(len(str)):
					enums.append(str[i]) 
				record.paramprop.append((name, enums))

			elif tokens[0] == 'paramlist':
				name = tokens[1]
				str = tokens[2:]
				list = []
				for i in range(len(str)):
					list.append(str[i]) 
				record.paramlist.append((name,list))

			elif tokens[0] == 'paramvec':
				name = tokens[1]
				str = tokens[2:]
				vec = []
				for i in range(len(str)):
					vec.append(str[i]) 
				record.paramvec.append((name,vec))

			elif tokens[0] == 'paramset':
				line = tokens[1:]
				result = []
				for i in range(len(line)):
					tset = line[i]
                                	if tset == '[':
                                        	nlist = []
                                	elif tset == ']':
                                        	result.append(nlist)
						nlist = []
                                	else:
                                        	nlist.append(tset)
				if result != []:
					record.paramset.append(result)

			elif tokens[0] == 'paramaction':
				name = tokens[1]
				str = tokens[2:]
				list = []
				for i in range(len(str)):
					list.append(str[i]) 
				record.paramaction.append((name,list))

			elif tokens[0] == 'category':
				record.category = tokens[1]

			elif tokens[0] == 'offset':
				if tokens[1] == '?':
					record.offset = -2
				else:
					record.offset = int(tokens[1])

			elif tokens[0] == 'alias':
				record.alias = tokens[1]

			elif tokens[0] == 'vectoralias':
				record.vectoralias = tokens[1]

			elif tokens[0] == 'props':
				record.props = tokens[1:]

			elif tokens[0] == 'chromium':
				record.chromium = tokens[1:]

			elif tokens[0] == 'vector':
				vecName = tokens[1]
				vecSize = int(tokens[2])
				for i in range(len(record.params)):
					(name, type, oldSize) = record.params[i]
					if name == vecName:
						record.params[i] = (name, type, vecSize)
						break

			else:
				print 'Invalid token %s after function %s' % (tokens[0], record.name)
			#endif
		#endif
	#endfor
	specFile.close()
#enddef





# Dictionary [name] of APIFunction:
__FunctionDict = {}

# Dictionary [name] of name
__VectorVersion = {}

# Reverse mapping of function name aliases
__ReverseAliases = {}


def AddFunction(record):
	assert not __FunctionDict.has_key(record.name)
	#if not "omit" in record.chromium:
	__FunctionDict[record.name] = record



def GetFunctionDict(specFile = ""):
	if not specFile:
		specFile = "../glapi_parser/APIspec.txt"
	if len(__FunctionDict) == 0:
		ProcessSpecFile(specFile, AddFunction)
		# Look for vector aliased functions
		for func in __FunctionDict.keys():
			va = __FunctionDict[func].vectoralias
			if va != '':
				__VectorVersion[va] = func
			#endif

			# and look for regular aliases (for glloader)
			a = __FunctionDict[func].alias
			if a:
				__ReverseAliases[a] = func
			#endif
		#endfor
	#endif
	return __FunctionDict


def GetAllFunctions(specFile = ""):
	"""Return sorted list of all functions known to Chromium."""
	d = GetFunctionDict(specFile)
	funcs = []
	for func in d.keys():
		rec = d[func]
		if not "omit" in rec.chromium:
			funcs.append(func)
	funcs.sort()
	return funcs
	

def GetDispatchedFunctions(specFile = ""):
	"""Return sorted list of all functions handled by SPU dispatch table."""
	d = GetFunctionDict(specFile)
	funcs = []
	for func in d.keys():
		rec = d[func]
		if (not "omit" in rec.chromium and
			not "stub" in rec.chromium and
			rec.alias == ''):
			funcs.append(func)
	funcs.sort()
	return funcs


#======================================================================

def ReturnType(funcName):
	"""Return the C return type of named function."""
	d = GetFunctionDict()
	return d[funcName].returnType


def Parameters(funcName):
	"""Return list of tuples (name, type, vecSize) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].params

def ParamAction(funcName):
	"""Return list of names of actions for testing."""
	d = GetFunctionDict()
	return d[funcName].paramaction

def ParamList(funcName):
	"""Return list of tuples (name, list of values) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].paramlist

def ParamVec(funcName):
	"""Return list of tuples (name, vector of values) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].paramvec

def ParamSet(funcName):
	"""Return list of tuples (name, list of values) of function parameters."""
	d = GetFunctionDict()
	return d[funcName].paramset


def Properties(funcName):
	"""Return list of properties of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].props


def Category(funcName):
	"""Return the category of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].category


def ChromiumProps(funcName):
	"""Return list of Chromium-specific properties of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].chromium

def ParamProps(funcName):
	"""Return list of Parameter-specific properties of the named GL function."""
	d = GetFunctionDict()
	return d[funcName].paramprop

def Alias(funcName):
	"""Return the function that the named function is an alias of.
	Ex: Alias('DrawArraysEXT') = 'DrawArrays'.
	"""
	d = GetFunctionDict()
	return d[funcName].alias


def ReverseAlias(funcName):
	"""Like Alias(), but the inverse."""
	d = GetFunctionDict()
	if funcName in __ReverseAliases.keys():
		return __ReverseAliases[funcName]
	else:
		return ''


def NonVectorFunction(funcName):
	"""Return the non-vector version of the given function, or ''.
	For example: NonVectorFunction("Color3fv") = "Color3f"."""
	d = GetFunctionDict()
	return d[funcName].vectoralias


def VectorFunction(funcName):
	"""Return the vector version of the given non-vector-valued function,
	or ''.
	For example: VectorVersion("Color3f") = "Color3fv"."""
	d = GetFunctionDict()
	if funcName in __VectorVersion.keys():
		return __VectorVersion[funcName]
	else:
		return ''


def GetCategoryWrapper(func_name):
	"""Return a C preprocessor token to test in order to wrap code.
	This handles extensions.
	Example: GetTestWrapper("glActiveTextureARB") = "CR_multitexture"
	Example: GetTestWrapper("glBegin") = ""
	"""
	cat = Category(func_name)
	if (cat == "1.0" or
		cat == "1.1" or
		cat == "1.2" or
		cat == "Chromium" or
		cat == "GL_chromium"):
		return ''
	elif cat[0] =='1':
		# i.e. OpenGL 1.3 or 1.4 or 1.5
		return "OPENGL_VERSION_" + string.replace(cat, ".", "_")
	else:
		assert cat != ''
		return string.replace(cat, "GL_", "")


def CanCompile(funcName):
	"""Return 1 if the function can be compiled into display lists, else 0."""
	d = GetFunctionDict()
	props = Properties(funcName)
	if ("nolist" in props or
		"get" in props or
		"setclient" in props or
		"useclient" in props):
		return 0
	else:
		return 1


def CanPack(funcName):
	"""Return 1 if the function can be packed, else 0."""
	d = GetFunctionDict()
	props = ChromiumProps(funcName)
	if ("pack" in props) or ("extpack" in props):
		return 1
	# check for packable alias
	alias = NonVectorFunction(funcName)
	if alias:
		props = ChromiumProps(alias)
		if ("pack" in props) or ("extpack" in props):
			return 1
	# check for vector version of packing function
	alias = VectorFunction(funcName)
	if alias:
		props = ChromiumProps(alias)
		if ("pack" in props) or ("extpack" in props):
			return 1
	return 0


def FuncGetsState(funcName):
	"""Return 1 if the function gets GL state, else 0."""
	d = GetFunctionDict()
	props = Properties(funcName)
	if "get" in props:
		return 1


def IsPointer(dataType):
	"""Determine if the datatype is a pointer.  Return 1 or 0."""
	if string.find(dataType, "*") == -1:
		return 0
	else:
		return 1


def PointerType(pointerType):
	"""Return the type of a pointer.
	Ex: PointerType('const GLubyte *') = 'GLubyte'
	"""
{'fraction_non_alphanumeric': 0.1542706828966371, 'fraction_numerical': 0.008923045182587167, 'mean_word_length': 3.420656634746922, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5594760', 'n_tokens_mistral': 7057, 'n_tokens_neox': 6171, 'n_words': 1846}