Files @ 66a28343341c
Branch filter:

Location: libtransport.git/backends/libpurple/gen_dynamic_purple.py - annotation

vitalyster
Merge pull request #2 from mcepl/fix_build_tarball

Make the build_*.sh scripts a little bit more robust.
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
9d96506fce9e
ac88ee23b0cf
7d6bef6ac6d1
7d6bef6ac6d1
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
7c7da424b6e4
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
7d6bef6ac6d1
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
6a998310e0e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
6a998310e0e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
7d6bef6ac6d1
7d6bef6ac6d1
7d6bef6ac6d1
7d6bef6ac6d1
7d6bef6ac6d1
dea27821a7e8
592c3ab0d88f
dea27821a7e8
592c3ab0d88f
d241422571c6
7d6bef6ac6d1
7d6bef6ac6d1
7d6bef6ac6d1
592c3ab0d88f
592c3ab0d88f
dea27821a7e8
dea27821a7e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
2faab40fad47
2faab40fad47
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
b3cdfe561929
b3cdfe561929
b3cdfe561929
b3cdfe561929
b3cdfe561929
b3cdfe561929
b3cdfe561929
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
2faab40fad47
2faab40fad47
592c3ab0d88f
dea27821a7e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
b3cdfe561929
b3cdfe561929
6a998310e0e8
6a998310e0e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
b3cdfe561929
b3cdfe561929
6a998310e0e8
6a998310e0e8
b3cdfe561929
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
1fde5bad9db4
592c3ab0d88f
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
d241422571c6
592c3ab0d88f
328ba6166b6f
328ba6166b6f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
c031ba344efa
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
1fde5bad9db4
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
1fde5bad9db4
d91990a491ab
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
036b2a30b94c
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
dea27821a7e8
dea27821a7e8
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
592c3ab0d88f
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
dea27821a7e8
592c3ab0d88f
import sys
import os

# intialize for methods used in libpurple macros
methods = ["purple_connection_get_state(", "purple_conversation_get_im_data(",
			"purple_conversation_get_chat_data(", "purple_blist_node_get_type("]
macros = ["PURPLE_CONV_IM", "PURPLE_CONV_CHAT", "PURPLE_BLIST_NODE_IS_BUDDY", "PURPLE_CONNECTION_IS_CONNECTED"]
definitions = []

if len(sys.argv) != 2:
	print "Usage:", sys.argv[0], "<path_to_libpurple_dir_containing_libpurple_headers>"
	sys.exit(1)


def handle_file(cpp):
	global methods
	global macros
	sys.stdout.write("getting used methods in " + cpp + ": ")
	sys.stdout.flush()

	counter = 0

	new_file = ""
	f = open(cpp, "r")
	for line in f.readlines():
		new_line = ""
		index = 0
		while index < len(line):
			new_line += line[index]
			if line[index:].startswith("purple_") or line[index:].startswith("wpurple_") or line[index:].startswith("serv_"):
				if line[index:].find("=") != -1 and line[index:].find("=") < line[index:].find("("):
					index += 1
					continue
				if line[index-1] == "_" or line[index:].find("(") == -1 or line[index:].startswith("purple_commands_init") or line[index:].startswith("serv_addr"):
					index += 1
					continue
				m = line[index:line[index:].find("(")+index]
				index += len(m)
				if m.find("_wrapped") != -1:
					new_line += m[1:] + "("
					m = m.replace("_wrapped", "")
				else:
					new_line += m[1:] + "_wrapped("
				if not m + "(" in methods and len(m) != 0:
					methods += [m + "("]
					counter += 1
			index += 1

		for x in macros:
			if new_line.find(x + "_WRAPPED") == -1:
				new_line = new_line.replace(x, x + "_WRAPPED")
		new_file += new_line
	f.close()

	print counter, "new methods found"
	return new_file

def handle_header(header, method):
	global definitions

	f = open(os.path.join(sys.argv[1], header), "r")

	lines = f.readlines()
	for i in range(len(lines)):
		line = lines[i]
		if line.find(method) != -1:
			if line.startswith(method):
				line = lines[i-1][:-1] + line
			m = line[:-1]
			l = unicode(m).strip()
			if l.endswith(")"):
				continue

			if m.find("/*") > m.find(";"):
				m = m[:m.find("/*")]
				m.rstrip()
				if len(m) != 0:
					while m[-1] == " ":
						m = m[:-1]

			index = i;
			while not m.endswith(";"):
				index += 1
				m += " " + lines[index][:-1].lstrip()

			l = unicode(m).strip()
			if (l.startswith("#") or l.startswith("*") or l.startswith("/*") or l.count("***") != 0 or l.count("&&") != 0
				or l.endswith(")")):
				continue;

			m = m.replace("G_GNUC_NULL_TERMINATE", "")

			if not m in definitions:
				print "found", method[:-1], "in", header
				definitions += [m]
			break
	f.close()

def get_raw_args(d):
	return d[d.find("(")+1:-2]

def get_args(d):
	x = d[d.find("(")+1:-2]
	x = x.split(",")

	args = []
	for arg in x:
		y = arg.split(" ")
		if len(y) == 1:
			continue
		args += [y[-1].replace("*", "")]

	return args

def get_name(d):
	x = d[:d.find("(")+1].lstrip()
	if x.find("wpurple_") != -1:
		return x[x.find("wpurple_"):]
	if x.find("serv_") != -1:
		return x[x.find("serv_"):]
	return x[x.find("purple_"):]

def get_rtype(d):
	if d.find("wpurple_") != -1:
		return d[:d.find("wpurple_")].lstrip()
	if d.find("serv_") != -1:
		return d[:d.find("serv_")].lstrip()
	return d[:d.find("purple_")].lstrip()

def output():
	global definitions

	header = open("purple_defs.h", "w")
	print >> header, "#pragma once"
	print >> header, "#if PURPLE_RUNTIME"

	print >> header, """
#include <Windows.h>
#include <purple.h>

#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED(n)    (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CHAT_NODE)
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED(n)   (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_BUDDY_NODE)
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED(n) (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_CONTACT_NODE)
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED(n)   (purple_blist_node_get_type_wrapped(n) == PURPLE_BLIST_GROUP_NODE)

#define PURPLE_CONV_IM_WRAPPED(c) (purple_conversation_get_im_data_wrapped(c))
#define PURPLE_CONV_CHAT_WRAPPED(c) (purple_conversation_get_chat_data_wrapped(c))

#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED(gc) \
	(purple_connection_get_state_wrapped(gc) == PURPLE_CONNECTED)
"""

	for d in definitions:
		#typedef void (_cdecl * purple_util_set_user_wrapped_func)(const char *dir);
		print >> header, "typedef", get_rtype(d), "(_cdecl *", get_name(d)[:-1] + "_wrapped_fnc)(" + get_raw_args(d) + ");"
		#extern purple_util_set_user_wrapped_func purple_util_set_user_wrapped;
		print >> header, "extern", get_name(d)[:-1] + "_wrapped_fnc", get_name(d)[:-1] + "_wrapped;"
		print >> header, ""

	print >> header, ""
	print >> header, "#else"
	print >> header, ""

	print >> header, """
#define PURPLE_BLIST_NODE_IS_CHAT_WRAPPED PURPLE_BLIST_NODE_IS_CHAT
#define PURPLE_BLIST_NODE_IS_BUDDY_WRAPPED PURPLE_BLIST_NODE_IS_BUDDY
#define PURPLE_BLIST_NODE_IS_CONTACT_WRAPPED PURPLE_BLIST_NODE_IS_CONTACT
#define PURPLE_BLIST_NODE_IS_GROUP_WRAPPED PURPLE_BLIST_NODE_IS_GROUP

#define PURPLE_CONV_IM_WRAPPED PURPLE_CONV_IM
#define PURPLE_CONV_CHAT_WRAPPED PURPLE_CONV_CHAT

#define PURPLE_CONNECTION_IS_CONNECTED_WRAPPED PURPLE_CONNECTION_IS_CONNECTED	
"""

	for d in definitions:
		#define purple_util_set_user_wrapped purple_util_set_user
		print >> header, "#define", get_name(d)[:-1] + "_wrapped", get_name(d)[:-1]
			
	print >> header, "#endif"
	print >> header, ""
	print >> header, "bool resolvePurpleFunctions();"
	print >> header, ""


	cpp = open("purple_defs.cpp", "w")
	print >> cpp, "#include \"purple_defs.h\""
	print >> cpp, ""
	print >> cpp, "#if PURPLE_RUNTIME"
	print >> cpp, "static HMODULE f_hPurple = NULL;"
	for d in definitions:
		#purple_util_set_user_wrapped_fnc purple_util_set_user_wrapped = NULL;
		print >> cpp, get_name(d)[:-1] + "_wrapped_fnc", get_name(d)[:-1] + "_wrapped = NULL;"

	print >> cpp, "#endif"

	print >> cpp, "bool resolvePurpleFunctions() {"
	print >> cpp, "#if PURPLE_RUNTIME"
	print >> cpp, "\tf_hPurple = LoadLibrary(L\"libpurple.dll\");"
	print >> cpp, "\tif (!f_hPurple)"
	print >> cpp, "\t\t\treturn false;"
	for d in definitions:
		#purple_util_set_user_wrapped = (purple_util_set_user_wrapped_func)GetProcAddress(f_hPurple, "purple_util_set_user_dir");
		print >> cpp, "\t" + get_name(d)[:-1] + "_wrapped = (" + get_name(d)[:-1] + "_wrapped_fnc)GetProcAddress(f_hPurple, \"" + get_name(d)[:-1] + "\");"
		#if (!purple_util_set_user_wrapped)
		print >> cpp, "\tif (!" + get_name(d)[:-1] + "_wrapped)"
		print >> cpp, "\t\treturn false;"
		print >> cpp, ""
	print >> cpp, "#endif"

	print >> cpp, "\treturn true;"
	print >> cpp, "}"
	print >> cpp, ""

	cpp.close()
	header.close()
		

for f in os.listdir("."):
	if not f.endswith(".cpp") or f.startswith("purple_defs"):
		continue
	new_file = handle_file(f)

	print "updating", f
	fd = open(f, "w")
	fd.write(new_file)
	fd.close()

for f in os.listdir(sys.argv[1]):
	if not f.endswith(".h"):
		continue
	for m in methods:
		handle_header(f, m)

sys.argv[1] = sys.argv[1] + "/win32"
for f in os.listdir(sys.argv[1]):
	if not f.endswith(".h"):
		continue
	for m in methods:
		handle_header(f, m)

for m in methods:
	found = False
	for d in definitions:
		if d.find(m[:-1]) != -1:
			found = True
			break
	if not found:
		print "NOT FOUND:", m

output()