def write_matlab_defs(cfg, defs): """Write a file containing the definition used in the package. """ contents = DEF_FILE % (cfg['xcpp']['filename'], date(), _format_defs(defs)) base = cfg['matlab']['pkg'] pkg = cfg['xcpp']['filename'] in_fname = '%s/xc_def.m' % base trace('* inspecting +%s/xc_def.m ... ' % pkg) write_file(in_fname, contents) if defs.keys(): inputs = 'The posible inputs are: \n%%\n%% %s' inputs = inputs % '\n%% '.join(defs.keys()) else: inputs = '' contents = XC_STRUCT_FILE.format(pkg=pkg, date=date(), inputs=inputs) in_fname = '%s/xc_struct.m' % base trace('* inspecting +%s/xc_struct.m ... ' % pkg) write_file(in_fname, contents)
def write_python_file(xcf, cfg, in_map, defs): """Writes the py file. """ body = ''.join([_fm_py_func(func, cfg, in_map) for func in xcf.function]) content = PY_FILE.format(date=date(), doc=xcf.docstring, load=cfg['python']['load'].capitalize(), dump=cfg['python']['dump'].capitalize(), mod=cfg['xcpp']['filename'], defs=_format_defs(defs), body=body) _write_py_file(content, cfg)
def _format_help(func, pkg): """Generate the help string for matlab functions. """ msg = '%% %s.%s generated on %s by xcpp\n\n %s' msg = msg % (pkg, func.name.upper(), date(), func.doc) if func.param: msg += '\n\n parameters:\n\n' tmp = ' {0}: {1}\n' for par in func.param: msg += tmp.format(par['name'], par['desc']) msg += ' ' msg = msg.split('\n') msg = '\n% '.join(msg) return msg
def write_cpp_file(xcf, cfg): """Writes the cpp file and compiles it. """ tmp = ' void {name}_py(size_t, char*, size_t&, char*&);\n' \ ' void {name}_py_clear();\n' extern = ''.join([tmp.format(name=func.name) for func in xcf.function]) body = ''.join([_fmt_func(func, cfg) for func in xcf.function]) epilog = xcf.epilog if epilog != '': epilog = '\n' + epilog content = FILE.format(date=date(), doc=xcf.docstring, pre_xc=xcf.pre_xc, preamble=xcf.preamble, extern=extern, body=body, epilog=epilog) in_fname = _write_cpp_file(content, cfg) _compile_cpp_file(in_fname, cfg)
def write_cpp_function(xcf, func, cfg): """Writes the cpp file and compiles it. """ fepi = func.epilog if fepi != '': fepi = '\n' + fepi if xcf.epilog != '': fepi += '\n' content = FILE.format(date=date(), preamble=xcf.preamble, load=cfg['matlab']['load'].capitalize(), inputs=format_input(func.param), body=func.body, funcpre=func.preamble, dump=cfg['matlab']['dump'].capitalize(), outputs=format_return(func.ret), funcepi=fepi, epilog=xcf.epilog) in_fname = _write_cpp_file(content, func, cfg) _compile_cpp_file(in_fname, func, cfg)
def write_cpp_file(xcf, cfg, in_map): """Writes the cpp file and compiles it. """ write_tm_file(xcf.function, cfg, in_map) fncs = [fmt_func(func) for func in xcf.function] epi = xcf.epilog if epi != '': epi = '\n' + epi content = FILE.format(date=date(), preamble=xcf.preamble, doc=xcf.docstring, pre_xc=xcf.pre_xc, functions='\n'.join(fncs), epilog=epi) in_fname = write_cpp_code(content, cfg) out_fname = _get_exec_name(cfg) fname = cfg['xcpp']['filename'] mma = cfg['mathematica']['mlink'] # COMPILING CODE _compile(fname, mma, in_fname, cfg) # LINKING _link(fname, mma, out_fname, cfg)
def process_function(xcf, cfg, func): """Given a Function object from .xcpp it will create the contents of a valid cpp file that can be compiled for a valid executable. """ in_fname = cfg['xcpp']['filename'] epilog = func.epilog if epilog != '': epilog += '\n' contents = TEMPLATE.format(date=date(), pre_xc=xcf.pre_xc, preamble=xcf.preamble, help=_format_help(func, in_fname), param=_format_input(func.param), doc=func.doc, body=func.body, load=cfg['cpp']['load'].capitalize(), dump=cfg['cpp']['dump'].capitalize(), input=format_input(func.param), output=format_return(func.ret), out=func.out, funcpre=func.preamble, funcepi=epilog, epilog=xcf.epilog) in_fname = _write_file(contents, func, cfg) out_fname = _get_exec_name(func, cfg) force = cfg['cpp']['force'] make_new = True if isinstance(force, list) and (len(force) == 0 or func.num in force): pass elif force in ['True', 'true']: pass elif os.path.exists(out_fname): date_in = datetime.fromtimestamp(os.path.getmtime(in_fname)) date_out = datetime.fromtimestamp(os.path.getmtime(out_fname)) if date_in < date_out: make_new = False trace(' - skipping compilation\n') if make_new: cmd = gen_cmd(cfg, 'cpp', int(cfg['cpp']['debug'])) cmd = '%s%s -o %s' % (cmd, in_fname, out_fname) trace(' - compiling %s ... ' % in_fname) _, err, _ = exec_cmd(cmd) if err != '': msg = "\nERROR: The command\n%s\n\nreturned the following " \ "error:\n%s" % (str(cmd), str(err)) error(msg) trace('done\n')
def write_m_file(xcf, cfg): """Writes the m file. """ root = cfg['xcpp']['root'] app = cfg['mathematica']['app'] usage = '\n\n'.join([_format_help(func, cfg) for func in xcf.function]) pkgname = cfg['xcpp']['filename'] funcnames = ',\n '.join([m_name(func.name) for func in xcf.function]) errors = '\n'.join([_format_error(func, cfg) for func in xcf.function]) content = M_FILE.format(date=date(), app=app, pkgname=pkgname, error=errors, usage=usage, funcnames=funcnames) dest_dir = '%s/%s' % (cfg['mathematica']['mma'], app) if dest_dir[0] == '/': base = dest_dir else: base = '%s/%s' % (root, dest_dir) filename = cfg['xcpp']['filename'] in_fname = '%s/%s.m' % (base, filename) trace('+ inspecting %s/%s.m ... ' % (app, filename)) write_file(in_fname, content)
def gen_input_file(xcfile, filename): """Generate the input file and return the name of the file it prints along with a dictionary containing the datatypes it contains. """ funcpre = ''.join([func.preamble for func in xcfile.function]) cont = """// Temporary file generated on {date} by xcpp. {pre_xc}#include <excentury/excentury.h> {preamble}{funcpre} int main() {{ excentury::TextInterface<excentury::dump_mode> XC_DI_(stdout); %s XC_DI_.close(); }} """.format(date=date(), pre_xc=xcfile.pre_xc, preamble=xcfile.preamble, funcpre=funcpre) var = dict() num = 1 tmp1 = ' {type} {var}{ctor}; XC_DI_.dump({var}, "{var}");\n' tmp2 = ' {type} {var}{ctor}; XC_DI_.dump({var}, "{var}", {sample});\n' inputs = '' for func in xcfile.function: for par in func.param: if par['type'] not in var: vname = 'var%d_%s' % (num, par['name'][1:-1]) var[par['type']] = vname if 'sample' in par: sample = par['sample'].replace(par['name'][1:-1], vname) inputs += tmp2.format(type=par['type'], var=vname, ctor=par['ctor'], sample=sample) else: inputs += tmp1.format(type=par['type'], var=vname, ctor=par['ctor']) num += 1 fname = 'inputs-%s.cpp' % filename trace('+ writing temporary file %s ... ' % fname) with open(fname, 'w') as tmp: tmp.write(cont % inputs) trace('done\n') return fname, var