Esempio n. 1
0
def extract_header(filepath):
	""" Called from our call to walk_files. It extract just the preprocessor crap and saves it into a file in
	    our project's include folder. """
	incfile = os.path.basename(filepath)
	log(bright('    Processing', 'white'), incfile + '..')
	content = extract_preprocessor(read_text(filepath))
	outpath = env.root_file('include', incfile)
	write_lines(env.root_file('include', 'python', incfile), remove_blanks(split_lines_rtrim(content)))
	return outpath
Esempio n. 2
0
def extract_exports(tabbase, source, arch):
	""" Extract our exported items from our preprocessed source code.
	    The tabbase argument specifies the resulting filename to write
	    our generated code to. (src/tabbase.c and include/tabbase.h)
	    Afterwards, we'll return the source code, with all the export
	    declarations removed. """
	# A collection of indexes to remove from the source
	removal_queue = []

	# Get our python DLL exports.
	dllname = 'python27.%s.dll' % arch
	log(bright('Build:', 'green'), bright('Processing','white'), dllname, bright('exports..\n', 'white'))
	exports = get_dllexports(dllname)

	# Generate the appropriate prototypes. We'll only keep stuff found exported from
	# our DLL
	log(bright('Build:', 'green'), bright('Processing export declarations..\n','white'))
	protos = filter(lambda p: p.name in exports, parse_declarations(source))

	# Generate our source files.
	macros = []
	entries = []
	for proto in protos:
		macro, entry = generate_tab(proto)
		macros.append(macro)
		entries.append(entry)
		if proto.valid_indexes: removal_queue.insert(0, [proto.start_index, proto.end_index])
	# Write the files.
	write_lines(env.root_file('src', tabbase+'.c'), entries)
	write_lines(env.root_file('include', tabbase+'.h'), macros)

	# Remove our declarations from the initial source code.
	buffer = filter(lambda c: ord(c) != 13, list(source))
	for removal in removal_queue:
		del buffer[removal[0]:removal[1]]
	return ''.join(buffer)
Esempio n. 3
0
def preprocess_sources(*srcs):
	""" Preprocess python.c, filter out the crap, clean it up, and
	    get the result as a string. """
	args = [ os.path.join(env.bin_dir, 'msvcpp.bat')] + \
		   [ '-I%s' % env.root_file('include') ] + \
		   [ env.data_file(s) for s in srcs ]
	print ' '.join(args)
	try:
		processed = subproc.check_output(args, stderr=subproc.VOID)
	except subproc.CalledProcessError:
		print 'Command Args:', args
		raise

	processed_parts = processed.split('void landmark();')
	if len(processed_parts) == 1:
		raise Exception('Could not find our landmark in pyport.h')

	filtered = '\n'.join(filter(
		lambda l: not l.startswith('#pragma') and len(l) > 0,
		split_lines_trim(processed_parts[1])
	))

	# Some formatting issues.
	filtered = re.sub(
		r"(?m)PythonDynLoad_(\w+)\s*\(([^)]+)\)\s*([^\s])",
		r"PythonDynLoad_\1(\2) \3",
		re.sub(
			r"(?m)\r?\n\)", ")",
			re.sub("(?m)([^;\r{])\r?\n", r"\1 ", filtered)
		)
	)

	# Compress structs, etc down to a single line.
	filtered = re.sub(
		r"(?sm)\{[\t ]*\r?\n(.+?)\r?\n\}",
		linearize_struct,
		re.sub(
			r"(?m)\{\s*\r?\n([^{}]+?)\}",
			linearize_struct,
			filtered
		)
	)

	# Filter out extra spaces.
	return condense_space(filtered)
Esempio n. 4
0
def extract_typedecls(source):
	"""
		Extract type definitions from the remaining source.

		NOTE: This function will be written into the existing state machine that
		handles extracting the preprocessor crap.
	"""
	typedecls = ['typedef', 'union', 'struct']
	src_template = """
#ifndef _DYNPYTHON_TYPES_H_
#define _DYNPYTHON_TYPES_H_
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

# if defined (_WIN64)
	typedef __int64 ssize_t;
#elif defined (_WIN32)
	typedef int ssize_t;
#endif

%(decls)s

#ifdef __cplusplus
}
#endif

#endif /* _DYNPYTHON_TYPES_H_ */
"""
	# Our filter function.
	def is_typedecl(line):
		for t in typedecls:
			if line.startswith(t):
				return True
		return False
	log(bright('Build:', 'green'), bright('Processing type declarations..\n','white'))
	lines = src_template % { 'decls' : '\n'.join(filter(is_typedecl, split_lines_clean(source))) }
	write_text(env.root_file('include', 'dynpython_types.h'), lines)