def error_message(description, summary): """ Print a pretty error message. """ from colorplus import coutput, bright coutput( lpad('$label $description', count=1), '', lpad_lines(break_up_lines(summary,81), count=1), label=bright('Error:', 'red'), description=bright(description, 'white'), seperator='\n' )
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
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)
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)
def main(tabbase): preprocessed = preprocess_sources('python.c') preprocessed = extract_exports(tabbase, preprocessed, 'x86') extract_typedecls(preprocessed) log(bright('Build:', 'green'), bright('Processing header files..','white')) walk_files(env.inc_dir, extract_header, lambda p: p.endswith('.h'))